<template>
    <view class="view-page">
      <!-- 背景图 -->
      <image
        class="page-bg"
        :src="'https://cdn1.visiotrip.com/h5AndMini/2024-09-19/chat-bg.png'"
        mode="scaleToFill"
      />
      <!-- 顶部AI背景图 -->
      <image
        class="page-bg"
        src="../../static/ai/head/aiBackground.png"
        mode="widthFix"
        v-show="isShowAiGif"
      />
      <!-- 是否显示AI人物动画GIF -->
      <block v-if="isShowAiGif">
        <img
          class="ai-chat"
          v-show="isAiShow"
          :style="{
            height: '440rpx',
            width:  '440rpx',
            left: '143rpx',
            top: (navHeight - statusBarHeight) + 'px',
            transform: 'translate(0rpx, 0rpx)' + ' translateZ(0rpx)',
          }"
          :src="aiGifList[aiGifIndex]"
        />
        <!-- 这下面五个aiGIF在屏幕之外， 不清楚作用 -->
        <img
          class="ai-chat"
          :style="{
            height: aiImgHeight + 'px',
            width: aiImgWidth + 'px',
            left: '-500px',
            bottom: '310rpx',
          }"
          :src="aiGifList[1]"
        />
        <img
          class="ai-chat"
          :style="{
            height: aiImgHeight + 'px',
            width: aiImgWidth + 'px',
            left: '-354px',
            bottom: '310rpx',
          }"
          :src="aiGifList[2]"
        />
        <img
          class="ai-chat"
          :style="{
            height: aiImgHeight + 'px',
            width: aiImgWidth + 'px',
            left: '-354px',
            bottom: '310rpx',
          }"
          :src="aiGifList[3]"
        />
        <img
          class="ai-chat"
          :style="{
            height: aiImgHeight + 'px',
            width: aiImgWidth + 'px',
            left: '-354px',
            bottom: '310rpx',
          }"
          :src="aiGifList[4]"
        />
        <img
          class="ai-chat"
          :style="{
            height: aiImgHeight + 'px',
            width: aiImgWidth + 'px',
            left: '-354px',
            bottom: '310rpx',
          }"
          :src="aiGifList[5]"
        />
      </block>
      <!-- 顶部导航栏, showTabBar用于判断是否显示头部标题栏，navHeight 是头部标题栏高度 -->
      <view
        class="nav-bar"
        v-if="showTabBar"
        :style="[{ height: navHeight + 'px' }]"
      >
        <view class="nav-left-view">
          <!-- 返回按钮， 左上角 -->
          <image
            src="../../static/ai/head/chat-back.png"
            mode="scaleToFill"
            class="back-img"
            @click="toHome"
            :data-spmCntSuffix="'ChatAiPage.opeFloor@1.back@1'"
            :data-custom="1"
            :data-spm="{'pos': '返回'}"
          />
          <!-- 目的地选择按钮， 左上角 -->
          <view
            class="nav-left-box"
            @click="changeDest"
            :data-spmCntSuffix="'ChatAiPage.opeFloor@1.dest@1'"
            :data-custom="1"
            :data-spm="aiDestItem"
            :style="{
              zIndex: navIndex,
            }"
          >
            <text class="dest-name">{{ aiDestItem.destinationName }}</text>
            <!-- 向上向下箭头 -->
            <uni-icons
              :type="showDest ? 'top' : 'bottom'"
              color="#131328"
              size="14"
            ></uni-icons>
          </view>
        </view>
        <!-- 头顶正中间标题栏图片， 只有隐藏aiGIF时才显示 -->
        <image
          class="title"
          :src="chatTitle"
          mode="scaleToFill"
          v-if="!isShowAiGif"
        />
        <img 
          :style="{
            right: menuRight +'px'
          }"
          class="clear-icon" 
          src="../../static/ai/head/clear-icon.png"
          @click="clearMessage"
        >
      </view>
      <!-- .bg 背景图片样式，只有aiGIF显示时才显示背景图片 -->
      <view class="page-view" :class="isShowAiGif ? 'bg' : ''">
        <block v-if="topProductArr.length > 0">
          <!-- 推荐产品(商品)卡片，显示商品列表第一个 -->
          <product-service-card
            :recProductQa="topProductArr[0]"
            @signOutService="signOutService"
          />
        </block>
        <!-- 商品卡片底部间距 -->
        <view v-if="topProductArr.length > 0" style="height: 140rpx"></view>
        <!-- 用户输入与结果输出消息列表 -->
        <scroll-view
          :scroll-y="scrollable"
          class="scroll-view"
          :scroll-into-view="messageScrollIntoView"
          :enable-flex="true"
          :scroll-top="scrollTop"
          :refresher-enabled="showTabBar"
          :refresher-triggered="triggered"
          @refresherrefresh="onRefresh"
          @scroll="onScroll"
          @scrolltolower="scrolltolower"
          scroll-with-animation
        >
          <!-- 标志，id = scroll-top-id 用于回到该元素位置的标识， scroll-view scroll-into-view -->
          <view id="scroll-top-id" style="width: 100%;height: 1rpx;"></view>
          <!-- 聊天历史记录消息列表 -->
          <view 
            class="scroll-content" 
            :id="'scroll-record' + index" 
            style="padding-bottom: 0" 
            v-for="(item, index) in recordPage" :key="index">
              <recordMessage
                :item="item"
                :index="index"
                :conversationId="conversationId"
                @setTabBar="setTabBar"
                @onStrategyClick="onStrategyClick"
                @guidingSuggestActions="guidingSuggestActions"
                @sureClickCall="sureClickCall"
                @showModal="showPopup"
                @getDspProduct="getDspProduct"
              ></recordMessage>
          </view>
          <view class="scroll-content" id="scroll-content">
            <!-- 历史记录与最新消息分割线, 只有隐藏aiGIF时 并且 有历史记录时 才显示 -->
            <view class="record-txt" v-if="showRecord && !isShowAiGif">
              <view class="border-box-left"></view>
              <view class="txt-box">
                {{recordPage.length > 0 ? showRecordTxt2 :showRecordTxt1}}
              </view>
              <view class="border-box-right"></view>
            </view>
            <!-- 最新消息列表, 当前用户输入与结果返回的数据展示 -->
            <block v-for="(item, index) in messageData.datas" :key="'messageData_' + index">
              <!-- :message="item.user" 用户输入 -->
              <Message
                mode="right"
                :message="item.user"
                :meId="`right-${index}`"
                class="message"
                v-if="!item.piolet"
              >
              </Message>
              <!-- :message="item.ai" 结果返回数据展示 -->
              <Message
                mode="left"
                v-if="item.ai"
                @showModal="showPopup"
                @sureClick="sureClick"
                @setTabBar="setTabBar"
                @onStrategyClick="onStrategyClick"
                :startProgress="startProgress"
                :message="item.ai"
                :travelerWith="travelerWith"
                :meId="`left-${index}`"
                @changeGifIndex="changeGifIndex"
                @sureClickCall="sureClickCall"
                @destClick="destClick"
                @getTemplateDestCard="getTemplateDestCard"
                class="message"
                @gotoOrderUrl="gotoOrderDetail"
                @onScrollToBottom="onScrollToBottom"
                @onClickEdit="onClickEditJoun"
                @editTripCardInfo="editTripCardInfo"
                @getDspProduct="getDspProduct"
                @callBackSetData="callBackSetData"
                @guidingSuggestActions="guidingSuggestActions"
                :actionList="actionList"
                @changeSendStatus="changeSendStatus"
                @feedbackCall="feedbackCall"
                :conversationId="conversationId"
                @setPrintedStatus="setPrintedStatus"
                @suggestClick="suggestClick"
                @signOutService="createChat"
                @changeQuestion="changeQuestion"
              >
              </Message>
            </block>
            <!-- 图片上传显示组件（手机拍摄或者相册获取的） -->
            <uni-transition :mode-class="['fade','slide-top']" :duration="300" :show="picUrlStatus">
              <view class="pic-status-box" v-if="picUrlStatus">
                <view class="pic-status-view">
                  <image
                    :src="picUrlStatus === 'error' ? 'https://cdn1.visiotrip.com/h5AndMini/2024-09-19/fail.png' : 'https://cdn1.visiotrip.com/h5AndMini/2024-09-19/loading.gif'"
                    mode="scaleToFill"
                    class="poi-status-img"
                  />
                </view>
              </view>
            </uni-transition>
            <!-- 详细列表底部高度， 用于监听键盘高度变化回弹 -->
            <view
              :style="{
                width: '100%',
                height: aiBottomY + 'rpx',
              }"
            ></view>
          </view>
          <view id="scroll-bottom-id" style="width: 100%;height: 1rpx;"></view>
        </scroll-view>
        <!--关键词列表，在用户输入内容但没点击确认发送按钮时调用接口，这个显示接口返回数据  -->
        <view class="keyWordBox" :style="{
          'bottom':(KeyoardHeight + tabBarHeight)+'px'
        }">
            <uni-transition :mode-class="['fade','slide-bottom']" :duration="300" :show="showKeyWord">
              <scroll-view scroll-y  class="keyList">
                <view class="key-flex" v-for="(item,index) in showKeyList" :key="index" @click="suggestClick(item)"
                :data-spmCntSuffix="'ChatAiPage.toolBar@5.hint@1'"
                :data-custom="index + 1"
                :data-spm="item"
                >
                  <view class="key-txt single-line-text">
                    <text class="key-txt-1">{{item.keyWord}}</text>
                    <text class="key-txt-2">{{item.showTxt}}</text>
                  </view>
                  <img class="key-icon" src="https://cdn1.visiotrip.com/h5AndMini/2023-09-14/key-icon.png" >
                </view>
              </scroll-view>
            </uni-transition>
          </view>
        <!-- 输入框左上角照相和地图导览按钮 -->
        <view
          id="input-box"
          v-if="setTabBarInput"
          :class="{'input-box':true,
            'ios-hid': isHide
          }"
          :style="{
            transform:
              'translate(0rpx, -' + aiBottomY + 'rpx)',
          }"
        >
          <view  style="position: relative;z-index: 2;display: flex;margin-left: 16rpx">
            <view
              class="phone-box"
              @click="takePhoneChange"
              :data-spmCntSuffix="'ChatAiPage.toolBar@5.takePhoneChange@'"
              :data-custom="1"
              :data-spm="1"
            >
              <image
                src="https://cdn1.visiotrip.com/h5AndMini/2024-09-19/ai-take-phone.png"
                mode="scaleToFill"
                class="phone-img"
              />
              <text>拍图识景</text>
            </view>
            <!-- yuanbin 20250506 暂时不显示地图导览 -->
            <!-- 只有新加坡目的地才有地图导览 -->
            <!-- <view class="mapClass_click" 
                v-if="showMapPreview"
                @click="mapClickTop"
                :data-spmCntSuffix="'mapClickTop.mapClickTop@5.hint@1'"
                data-custom="mapClickTop"
                :data-spm="1"
            >
              <img class="mapClass_img" src="https://cdn1.visiotrip.com/h5AndMini/2024-11-01/dingwei.png" />
              地图导览
            </view> -->
          </view>
          <!-- 这个地方应该被遗弃了 ， 因为v-if=“false” -->
          <view style="position: relative;z-index: 2;display: flex;" v-if="false">
            <!-- 如果目的地是上海的话则显示 -->
            <img
              v-if="aiDestItem.destinationId == 2"
              @click="suggestClick({actionText: '给我一份迪士尼专属攻略', styleType: '2'})" 
              class="chat-zn dsn" 
              src="https://cdn1.visiotrip.com/h5AndMini/2024-02-26/dsn-zn.png" 
              :data-spmCntSuffix="'ChatAiPage.toolBar@4@.preference@'"
              :data-custom="2"
              :data-spm="{pos: '迪士尼独家指南'}"
            >
            <scroll-view class="scroll-view-x" :style="aiDestItem.destinationId == 2 ? 'width: 60%' : ''" scroll-x="true" v-if="printedStatus && suggestActions.length > 0">
              <block
                v-for="(suggestItem,suggestIndex) in suggestActions" 
                :key="suggestIndex"
              >
              <view
                class="scroll-view-item_H" 
                @click="suggestClick(suggestItem)"
                :data-spmCntSuffix="'ChatAiPage.toolBar@4.preference@1'"
                :data-custom="suggestIndex + 1"
                :data-spm="suggestItem"
              >
                {{suggestItem.actionText}}
              </view>
              </block>
            </scroll-view>
          </view>
          <!-- 右下角回到底部按钮 -->
          <img class="to-bottom" 
            v-if="showBottom" 
            @click="toBottom" 
            src="https://cdn1.visiotrip.com/h5AndMini/2023-11-17/to-bottom.png">
          <!-- 正下方用户输入框 -->
          <view
            class="textarea-box"
            :class="{ 'border-none': aiBottomY > 0 }"
            id="my_component"
          >
            <view
              class="input-text-warp"
              @click="
                () => {
                  clickTxt = true;
                }
              "
              :class="{ 'border-none': aiBottomY != 0 }"
            >
              <view
                class="tab-voice"
                v-if="!clickTxt || recordStaus"
                :class="{ record: recordStaus }"
                :data-spmCntSuffix="'ChatAiPage.toolBar@2.switchover@1'"
                :data-custom="1"
                :data-spm="'1'"
                @click="onChangeLanguageType"
              ></view>
              <view
                v-if="!clickTxt"
                class="press-on-speak-icon-1"
              >旅行相关尽管问我</view>
              <textarea
                :focus="clickTxt"
                id="inputTextarea"
                @focus="focusInput"
                @blur="blurInput"
                v-if="!recordStaus && clickTxt"
                @linechange="onTextAreaHeightChange"
                :adjust-position="false"
                :cursor-spacing="textareaCursorSpace"
                @confirm="sendAiMessage"
                :disable-default-padding="true"
                :show-confirm-bar="false"
                confirm-type="send"
                :confirm-hold="true"
                class="input-textarea"
                :auto-height="true"
                v-model="input"
                placeholder-class="textarea-placeholder"
                @input="handleInput"
              />
              <!-- <view
                class="send-load-icon"
                v-show="sendStatus && !recordStaus"
              ></view> -->
              <view
                v-if="recordStaus"
                class="press-on-speak"
                @longpress="longpress"
                @touchmove="onTouchMove"
                @touchend="touchend"
                data-spmCntSuffix="'ChatAiPage.toolBar@2.input@2'"
                :data-custom="2"
                :data-spm="'2'"
              >
                按住说话
              </view>
            </view>
            <view
              v-if="!recordStaus"
              class="send-btn"
              :class="{ 'disabled': ((!input || input.length <= 0 || input.trim() === '') && !sendStatus), 'send-status': sendStatus }"
              @click.stop="onButtonClick"
              data-spmCntSuffix="'ChatAiPage.toolBar@2.sendMessage@1'"
              :data-custom="1"
              :data-spm="'1'"
            ></view>
            <!-- 语音按住说话 v-show="islongPress" -->
            <view v-show="islongPress"  class="talk_box" :style="{background: isCancel ? '#F93F55' : 'rgba(27, 156, 97, 1)'}" >
              <text class="talk_text" :style="{color: isCancel ? '#F93F55' : '#767697'}">{{isCancel ? '松手取消' : '松手发送，上移取消'}}</text>
              <audio-rate />
            </view>
          </view>
          <view
            :class="{ 'min-space': !showTabBar, 'max-space': showTabBar }"
          >对话由AI模型生成，仅作参考</view>
        </view>
        <!-- <viSioTabBar id="viSioTabBar" :tabIndex="1" v-if="showTabBar"></viSioTabBar> -->
      </view>
      <!-- 语音录频 -->
      <uni-popup
        ref="recordPopup"
        background-color="#fff"
        mask-background-color="rgba(26, 26, 26,0.85)"
      >
        <view class="popup-content">
          <view class="content-record-icon"></view>
        </view>
        <view class="record-bo-box">
          <view class="record-text">{{ !isCancel ? "松开 发送" : "" }}</view>
          <view class="record-can" :class="{ 'can-btn': isCancel }"></view>
          <view class="record-text record-text-can" v-if="isCancel"
            >松开 取消</view
          >
  
          <view class="record-icon"></view>
        </view>
      </uni-popup>
      <!-- 弹窗，不知道什么作用 -->
      <uni-popup ref="itinerary" background-color="#fff" :safeArea="false">
      </uni-popup>
      <!-- 攻略卡片 -->
      <hqsPopup
        ref="strategy"
        :height="'85vh'"
        :round="25"
        :showClose="false"
        :showHeader="false"
      >
        <view>
          <swiper
            style="width: 100%; height: 85vh"
            :interval="5000"
            ref="zSwiper"
            :current="swiperIndex"
            @change="handleSwiperChange"
          >
            <swiper-item
              v-for="(item, index) in cardList"
              :key="item.articleId"
              style="border-radius: 48rpx"
            >
              <scroll-view scroll-y style="height: 100%">
                <Strategy :detailData="item" ref="strategyDeatail">
                    <view class="printe-text">
                      <printe-text :text="loopAnswerList[index]"></printe-text>
                    </view>
                </Strategy>
              </scroll-view>
            </swiper-item>
          </swiper>
          <template v-slot:bottom>
            <view class="str-bottom" :style="{ 'z-index':  showStrategyListStrbottom? 0 : -1 }">
              <view
                class="bottom-box"
                :class="{ active: scaleChange }"
                @click="handStrategy(0)"
                :data-spmCntSuffix="`ChatAiPage.article@1.change`"
                :data-custom="1"
                :data-spm="1"
              >
                <img
                  class="icon-1"
                  :src="baseCdnUrl + '2023-08-29/change-icon.png'"
                />
                换一篇
              </view>
              <view class="bottom-box" 
                @click="handStrategy(1)"
                :data-spmCntSuffix="`ChatAiPage.article@1.detail`"
                :data-custom="1"
                :data-spm="1"
              >
                <img
                  class="icon-2"
                  :src="baseCdnUrl + '2023-08-29/detail-icon.png'"
                />
                看详情
              </view>
              <view
                class="bottom-box"
                :class="{ active: scaleCollect }"
                @click="handStrategy(2)"
                :data-spmCntSuffix="`ChatAiPage.article@1.collect`"
                :data-custom="1"
                :data-spm="1"
              >
                <img
                  class="icon-3"
                  :src="baseCdnUrl + '2023-08-29/like-icon.png'"
                />
                {{ cardList[swiperIndex] && cardList[swiperIndex].favorite ? "已收藏" : "收藏" }}
                <view
                  class="collect"
                  v-if="isShowStrategyCard"
                  @click.stop="handClose(1)"
                >
                  根据你的爱好规划路线
                  <img
                    class="collect-2"
                    :src="baseCdnUrl + '2023-08-29/collect-2.png'"
                  />
                </view>
                <img
                  v-if="isShowStrategyCard"
                  class="collect-1"
                  :src="baseCdnUrl + '2023-08-29/collect-1.png'"
                />
              </view>
            </view>
          </template>
        </view>
      </hqsPopup>
      <!-- 目的地选择弹窗 -->
      <uni-popup
        ref="maskDest"
        :mask-click="true"
        @maskClick="changeDest"
        :mask-background-color="'rgba(0,0,0,0.7)'"
      >
        <view class="maskDest" :style="'top:' + (navHeight + 10) + 'px'">
          <DestBox ref="destBox" @destClick="destClick" @fail="changeDest" />
        </view>
      </uni-popup>
      <!-- 首页目的地切换弹窗 -->
      <uni-popup
        ref="changeBox"
        :mask-click="true"
        :mask-background-color="'rgba(0,0,0,0.1)'"
        @maskClick="changeBox"
      >
        <view class="maskDest active" :style="'top:' + (navHeight + 10) + 'px'">
          <view class="changeBox">
            <img class="icon-2" :src="baseCdnUrl + '2023-7-19/dest-icon-2.png'" />
            <view class="changeTxt"
              >首页显示你浏览“{{ destItem.destinationName }}”</view
            >
            <view class="changeBtn" @click="changeClick">
              切换{{ destItem.destinationName }}
            </view>
          </view>
        </view>
      </uni-popup>
      <!-- 删除历史对话记录弹窗 -->
      <uni-popup
        ref="clearPopup"
        type="center"
        :safe-area="false"
      >
        <view class="clear-box">
          <view class="clear-title">确认删除历史聊天记录并开启新的对话吗？删除后不可撤销。</view>
          <view class="clear-txt-1" @click="sureClear(1)">确定删除</view>
          <view class="clear-txt-2" @click="sureClear(0)">不删除，仅开启新对话</view>
        </view>
      </uni-popup>
      <!-- 日历弹框 -->
      <uni-popup ref="calendar" type="bottom" :safe-area="false">
        <view class="calendarBox">
          <calendar
            :is-show="true"
            :theme-color="'#7696FF'"
            mode="1"
            @callback="calendarChange"
            ref="calendarBox"
          >
          </calendar>
        </view>
      </uni-popup>
      <!-- 如果显示关键词列表的话 -->
      <view class="key-mask" :style="{'top':'-'+ (tabBarHeight+KeyoardHeight)+'px'}" v-if="showKeyWord"></view>
      <!-- 是否同意手机号登录, 目前用于测试 -->
      <!-- <uni-popup ref="loginBox" :mask-click="false" type="center">
        <button
          class="btn-box active"
          open-type="getPhoneNumber"
          @getphonenumber="getPhoneNumber"
        >
          同意
        </button>
      </uni-popup> -->
    </view>
</template>
  
<script>
  import {
    newConversation,
    sendMessage,
    requestTips,
    requestMessageDetail,
    recItinerary,
    getUpcomingTravel,
    queryArticleDetail,
    queryPageRecommend,
    queryUserSummary,
    requestArticleLoopAnswer,
    queryCardTemplate,
    tripDetail,
    queryCardTemplateDest,
    getPromptRetrieve,
    getChatRecordPage,
    clearRecord,
    getClothes,
    getUserMessage
  } from "./serve/api.js"; // 接口引入
  import dsbridge  from "./utils/dsbridge.js";
  import Message from "./components/message.vue";
  import { newUpload } from "./utils/request/upload.js";
  import UniPopup from "../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue";
  // import {uniPopup} from '@dcloudio/uni-ui/lib/uni-popup/uni-popup.vue'
  import commonPopup from "./components/commonPopup/index.vue";
  import tripCard from "./components/tripCard.vue";
  import printeText from "./components/printeText.vue";
  import viSioMaskVue from "./components/viSioComponents/viSioMask.vue";
  import DestBox from "./components/destBox/destBox.vue";
  import hqsPopup from "./components/hqs-popup/hqs-popup.vue";
  import Strategy from "./components/strategy/strategy.vue";
  import slWatermark from './components/sl-watermark/sl-watermark.vue';
  import recordMessage from "./components/recordMessage.vue";
  import Calendar from "./components/Calendar.vue";
  import audioRate from './components/audioRate.vue';
  import ProductServiceCard from './components/productServiceCard.vue';
  import pointData from './utils/point.js'
  const globalData = uni.getStorageSync("globalData");
  let globalDspId = null;
  let globalPlaybackRate = "1.0";
  const recorderManager = uni.getRecorderManager();
  const maximumNumberOfRetries = 2;
  let journeyDemand = null;
  let sendTextObj = {
    // 即将需要发出的攻略数据
    needSendStatus: false,
    userText: "",
    aiText: "",
  };
  let globalNextScene = "";
  let globalPreSceneCode = "";
  let journeyPreference = ""; //出行卡片
  let favoritePoiList = []; //选择推荐景点列表
  let globalIsPollStatus =true
  
  let globalTriggerType = 1
  let userBehaviorDate = {}
  let topHomePageArr = []
  function throttle(func, limit) {  
      console.log('zhixing l==')
      let lastRan;  
      return function() {  
        const context = this;  
        const args = arguments;  
        const now = Date.now();  
        if (!lastRan || (now - lastRan >= limit)) {  
          func.apply(context, args);  
          lastRan = now;  
        }  
      };  
    };
  export default {
    components: {
      // 消息组件，用于显示聊天消息
      Message,
      // uni-popup 组件，用于创建弹出层
      UniPopup,
      // 自定义通用弹出层组件
      commonPopup,
      // 行程卡片组件
      tripCard,
      // 打印文本组件
      printeText,
      // 自定义遮罩层组件
      viSioMaskVue,
      // 目的地选择框组件
      DestBox,
      // 自定义弹出层组件，可能用于显示攻略等内容
      hqsPopup,
      // 攻略组件，用于展示攻略详情
      Strategy,
      // 水印组件
      slWatermark,
      // 聊天记录消息组件
      recordMessage,
      // 日历组件
      Calendar,
      // 音频速率组件
      audioRate,
      // 商品服务卡片组件
      ProductServiceCard,
    },
    data() {
      return {
        showMapPreview:false, // 是否显示地图预览
        travelerWith:false, // 未知用途，可能表示是否与旅行者相关的标识
        isAiShow: true, // 是否显示AI元素
        aiBottomY: 0, // AI元素底部的Y坐标偏移量
        aiBottom: "370rpx", // AI元素底部的距离
        baseCdnUrl: globalData.baseCdnUrl, // 基础CDN地址，从全局数据中获取
        scaleCollect: false, // 收藏相关的缩放状态标识
        scaleChange: false, // 切换相关的缩放状态标识
        isShowD: false, // 未知用途，可能表示是否显示某个特定元素D
        slideCustomStyle: {
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          borderRadius: "30rpx",
          transform: "rotate(0)",
        }, // 滑动组件的自定义样式
        options: {
          effect: "cards",
        }, // 某些组件的配置选项，效果为卡片样式
        cardList: [], // 卡片列表数据
        isShowCard: false, // 是否显示卡片
        isShowItineraryId: "", // 未知用途，可能表示是否显示行程ID
        errorText: [
          "很抱歉，网络连接中断，我暂时无法给你解答问题",
          "很抱歉，网络异常，我暂时无法回答你的问题",
          "非常抱歉，由于网络响应问题，我暂时无法给你提供帮助。希望你能理解",
          "非常抱歉，网络连接出现问题，我无法及时给你回答你的问题，请耐心等候",
        ], // 网络错误时显示的提示文本列表
        messageData: {
          datas: []
        }, // 消息数据列表
        tipsData: [], // 提示数据列表
        keyboardHeight: 0, // 软键盘的高度
        parentSpm: {
          ref: "",
          pre: "",
        }, // 父级SPM（可能是某种统计标识）配置对象
        imgUrls: [
          this.baseCdnUrl + "2023-06-22/input%402x.png",
          this.baseCdnUrl + "2023-06-22/close.png",
          this.baseCdnUrl + "2023-06-22/close-1.png",
          this.baseCdnUrl + "2023-06-22/record.png",
          this.baseCdnUrl + "2023-06-22/play-icon.gif",
          this.baseCdnUrl + "2023-06-22/left-btn2x.png",
          this.baseCdnUrl + "2023-06-22/right-btn2x.png",
          this.baseCdnUrl + "2023-09-14/zanting.png",
          this.baseCdnUrl + "2023-09-14/pay-2x.png",
          this.baseCdnUrl + "2023-09-14/cptext.png",
          this.baseCdnUrl + "2023-09-14/record-paying.png",
          this.baseCdnUrl + "2023-06-22/play-icon.gif",
        ], // 图片URL列表
        chatTitle: '', // 聊天页面的标题
        navHeight: globalData.navHeight, // 导航栏的高度，从全局数据中获取
        statusBarHeight: globalData.statusBarHeight, // 状态栏的高度，从全局数据中获取
        input: "", // 输入框的内容
        scrollTop: 0, // 滚动视图的滚动顶部位置
        messageScrollIntoView: undefined, // 滚动视图滚动到指定元素的ID
        rating: 0, // 评分值
        loadingTips: false, // 是否正在加载提示
        tipsModeClass: "fade", // 提示的过渡动画类名
        inputOffsetTop: 0, // 输入框的顶部偏移量
        isIos: uni.getSystemInfoSync().platform == "ios" ? true : false, // 是否为iOS平台
        textareaCursorSpace: uni.getSystemInfoSync().platform == "ios" ? 20 : 15, // 文本域光标与输入框的间距，根据平台不同设置不同值
        showTabBar: true, // 是否显示底部标签栏
        inMessageTips: [], // 消息内的提示列表
        pollingChatMessage: undefined, // 轮询的聊天消息对象
        figureObjList: [], // 未知用途，可能表示图形对象列表
        current: 0, // 未知用途，可能表示当前索引
        voicePath: "", // 语音文件的路径
        voiceTime: 0, // 录音时间
        recordStaus: false, // 录音状态
        islongPress: false, // 是否正在长按录音
        clientX: 360, // 客户端X坐标，可能用于触摸事件
        clientY: 700, // 客户端Y坐标，可能用于触摸事件
        isCancel: false, // 是否取消发送状态
        speechUrl: "", // MP3地址
        sendStatus: false, // 发送状态
        overview: "", // 未知用途，可能表示概述信息
        allDayList: [], // 未知用途，可能表示全天列表数据
        infoData: "", // 未知用途，可能表示信息数据
        dayNodeList: [], // 未知用途，可能表示日期节点列表数据
        itineraryPlanId: "", // 行程计划ID
        selectDspInfoId: "", // 未知用途，可能表示选择的DSP信息ID
        markers: [], // 地图标记列表
        polyline: [], // 地图折线数据列表
        includePoints: [], // 地图包含的点列表
        longitude: "", // 经度
        latitude: "", // 纬度
        dialogueModelAvatar: "", // 对话模型的头像地址
        selectedDspId: "", // 未知用途，可能表示选择的DSP ID
        robotObj: {}, // 机器人对象
        focusStatus: false, // 输入框焦点状态事件标识
        dspGetStatus: false, // 获取dsp卡片状态
        startProgress: false, // 是否开始进度
        fixedSceneCode: null, // 固定场景代码
        isShowStrategyCard: false, // 是否显示根据爱好规划路线的攻略卡片
        startY: 0, // 触摸开始时的Y坐标，可能用于滑动事件
        currentY: 0, // 触摸当前的Y坐标，可能用于滑动事件
        swiperIndex: 0, // 攻略卡片的当前位置索引
        liveList: [], // 喜欢的攻略列表
        loopAnswerList: [], // 循环回答列表
        setTabBarInput: true, // 是否设置底部标签栏的输入框
        scrollable: true, // 滚动视图是否可滚动
        showDest: false, // 是否显示目的地选择框
        aiDestItem: "", // 当前选择的AI目的地项
        aiDestList: [], // AI目的地列表
        showChangeDest: false, // 是否显示切换目的地的相关元素
        destItem: "", // 目的地项
        clickTxt: false, // 输入框是否被点击标识
        isHide: false, // 是否隐藏输入框
        aiGifList: [
        '', // 招呼 https://cdn1.visiotrip.com/h5AndMini/2024-0516/chat-type-1.gif
        '', // 自然站立 https://cdn1.visiotrip.com/h5AndMini/2024-0516/chat-type-2.gif
        '', // 思考 https://cdn1.visiotrip.com/h5AndMini/2024-0516/chat-type-3.gif
        '', // 推荐 https://cdn1.visiotrip.com/h5AndMini/2024-0516/chat-type-4.gif
        '', // 委屈 https://cdn1.visiotrip.com/h5AndMini/2024-0516/chat-type-5.gif
        '', // 站立说话 https://cdn1.visiotrip.com/h5AndMini/2024-0516/chat-type-6.gif
        ], // AI动画GIF图片列表
        aiGifIndex: 1, // 当前显示的AI动画GIF图片索引
        aiImgWidth: 0, // AI图片的宽度
        aiImgHeight: 0, // AI图片的高度
        aiImgLeft: 0, // AI图片的左侧偏移量
        keyboardHeight: 0, // 软键盘的高度（重复定义，可能需要检查）
        navIndex: 0, // 导航栏的索引
        swiperRequestLoading: false, // 攻略卡片滑动请求是否正在加载标识
        suggestActions:[],// 修改行程题词列表
        suggestActionsItem:'', // 修改行程题词的单个项
        showKeyWord:false, // 是否显示关键词列表
        tabBarHeight:0, // 底部标签栏的高度
        KeyoardHeight:0, // 可能是拼写错误，应为keyboardHeight，软键盘的高度
        keyWordList:[],// 服务端返回的关键词列表数据
        showKeyList:[],// 前端过滤后的关键词列表数组
        gifTimer:null, // GIF动画的定时器
        timeNum:0, // 未知用途，可能表示时间计数
        gifTimeout:null, // GIF动画的超时定时器
        optionsData:'', // 未知用途，可能表示选项数据
        shareText: '', // 扫描传的参数
        isFirstInit:true,// 是否第一次进入页面
        actionList:[], // 操作列表
        watermarkInfo: {}, // 水印信息对象
        triggered:false, // 滚动视图刷新触发状态
        recordPage:[], // 聊天记录页面数据列表
        recordPageNo:1, // 聊天记录的当前页码
        allPageNo:1,// 聊天记录的总页数
        detailPrams:{}, // 未知用途，可能表示详情参数
        showRecord: false, // 是否显示聊天记录提示
        showRecordTxt1:'下拉看看我们的聊天', // 聊天记录提示文本1
        showRecordTxt2:'以上是我们的回忆', // 聊天记录提示文本2
        menuRight:globalData.menuRight - 8, // 菜单右侧的偏移量，从全局数据中获取并减去8
        showBottom:false, // 是否显示底部相关元素
        lastScrollTop: 0, // 上一次滚动视图的滚动顶部位置
        conversationId: '', // 会话ID
        printedStatus: false, // 未知用途，可能表示打印状态
        showOrder: false, // 是否显示订单相关元素
        numberId: 0, // TODO 欢迎卡片调用次数
        isShowAiGif: true, // 是否显示AI人物动画GIF
        recProductQa: "", // 商品咨询卡片数据
        topProductArr: [], // 顶部商品数组
        picUrl: '', // 图片地址 
        picUrlStatus: '', // 图片状态
      };
    },
    computed: {
      // 计算属性，用于判断是否正在轮询聊天消息
      isPolling() {
        return (
          this.pollingChatMessage &&
          this.pollingChatMessage?.ai?.responseCompleted == false
        );
      },
      // 
      scrollViewStyle() {
        //减去出入框上边距
        let value = this.inputOffsetTop - 6;
        return `height: ${value * 2}rpx`;
      },
      // 攻略卡片弹窗底部按钮是否显示
      showStrategyListStrbottom: {
          get() {
              return this.$store.$state && this.$store.$state.showStrategyListStrbottom
          }
      }
    },
    watch: {
      // 监听攻略卡片当前索引变化
      swiperIndex: function (value) {
        // 当索引变化时，获取对应卡片的文章ID，并进行通用UUID处理
        let articleId = this.cardList[value].articleId;
        this.generalUUID(articleId, value);
      },
      "pollingChatMessage.ai.text": {
        deep: true,
        handler: function (val, oldVal) {
          // console.log(val, oldVal,'-------------------==============')
          // if(val != oldVal) {
          //   // this.onScrollToBottom();
          // }
        },
      },
      "pollingChatMessage.ai.responseCompleted": {
        deep: true,
        handler: function (value, old) {
          if (old === false && value === true) {
            this.sendStatus = false;
            this.pollFina();
          }
        },
      },
    },
    mounted(){
      uni.createSelectorQuery()
          .in(this)
          .select('#input-box')
          .boundingClientRect((rect) => {
            if (rect) {
              const height = rect.height;
              this.tabBarHeight = height
            }
          })
          .exec();
    },
    methods: {
      // 根据店铺与poi校验是否可以展示地图导览入口
      getMapPreview(destId) {
        this.$aiRequest({
          url: '/scenicSpot/displayMapGuideBtn',
          method: 'POST',
          params: {destId}
        }).then(result => {
          if (result.success) {
            this.showMapPreview = result.data;
          } else {
            this.showMapPreview = false
          }
        })
      },
      // 地图导览跳转
      mapClickTop() {
        this.$navTo('/ai/pages/mapPreview/mapPreview',{},'navigateTo')
      },
      ChatMessage(
        text, // 文本内容
        id, // id
        conversationId,  // 会话id
        chatId, // 聊天id
        recordStaus, // 记录状态
        voiceTime, // 语音时间
        speechUrl, // 语音地址
        piolet, // 是否是用户
        dialogueModelAvatar, // 机器人头像
        robotObj, // 机器人对象参数
        robotId, // 机器人id
        picUrl, // 图片地址
        responseCompleted = false, // 是否完成
      ) {
        const newMessageData = {}
        let curUser;
        // 获取token
        let token = uni.getStorageSync("Authentication");
        //  token存在才会去获取当前用户信息
        if (token) {
          // 获取当前用户信息
          curUser = uni.getStorageSync("currUser");
        }
        newMessageData.user = { // 用户输入参数， 可输入文本，语音，图片，
          speechUrl, // 语音地址
          voiceTime, // 语音时间
          recordStaus, // 记录状态
          text, // 文本内容(输入)
          avatar: // 用户头像
            curUser?.avatar ??
            "https://cdn1.visiotrip.com/h5AndMini/2023-06-22/touxiang.webp",
          picUrl,// 图片地址
        };
        this.$set(newMessageData, 'ai', {
          text: "管家正在思考中...", // 文本内容(输出)
          robotObj,
          responseCompleted: responseCompleted, // 是否完成
          pollAnswer: false, // 是否是轮询
          avatar: // 机器人头像
            dialogueModelAvatar ||
            "https://cdn1.visiotrip.com/h5AndMini/2023-3-29/chat_ai_heads.png",
          isOpen: false, // 是否开启
          isResetText: false, // 是否重置文本
          showNewChat:false, // 是否显示新的聊天
          itineraryTheme: null,// 主题模块
          showItineraryTheme: false, // 是否显示主题
          showItineraryCard: false, // 是否显示行程
          showHotelPriceParity: false, // 是否显示酒店价格
          showHotelPreference: false, // 是否显示酒店偏好
          showImgList: false, // 是否显示图片
          showCardList: false, // 是否显示卡片
          showContractCard: false, // 是否显示合同
          showRecRestaurant: false, // 是否显示推荐餐厅
          showMarket: false, // 是否显示市场
          showRefArticleList: false, // 是否显示参考攻略
          showSuggestActions: false, // 是否显示建议
          showProductQa: false, // 是否显示商品咨询
          refArticleList: [], // 参考攻略列表
          chatId: '' // 聊天id
        })
        newMessageData.ai.robotObj.playbackRate = globalPlaybackRate; // 返回结果的播放速度
        newMessageData.answered = false; // 是否回答
        newMessageData.ai.isShowMessage = true; // 是否显示消息弹窗
        newMessageData.ai.destId = uni.getStorageSync("aiDestItem").destinationId, // 目的地id
        newMessageData.id = id; // id
        newMessageData.piolet = piolet; // 是否是用户
        newMessageData.chatId = chatId; // 聊天id
        newMessageData.ai.chatId = chatId;  // 聊天id
        newMessageData.conversationId = conversationId;  // 会话id
        newMessageData.numberOfRetries = 0;  // 重试次数
        newMessageData.ai.startProgress = false;  // 是否开始进度
        newMessageData.ai.showRecRestaurant = false; //是否展示餐馆卡片
        newMessageData.ai.showMarket = false; //是否展示市场卡片
        newMessageData.ai.showItineraryTheme = false; //是否展示主题卡片
        newMessageData.ai.showItineraryCard = false;  //是否展示行程卡片
        newMessageData.ai.clickable = true //是否可操作卡片
        newMessageData.ai.showHotelPreference = false //是否展示酒店卡片
        newMessageData.ai.showHotelPriceParity = false  //是否展示酒店价格
        newMessageData.ai.showImgList = false //是否展示图片
        newMessageData.ai.showCardList = false  //是否展示卡片
        newMessageData.ai.showContractCard = false  //是否展示合同卡片
        newMessageData.ai.refArticleList = [] //参考攻略列表
        newMessageData.ai.suggestActions = [] // 建议列表
        newMessageData.ai.recProductQa = {} // 推荐产品
        newMessageData.requestMessage = async () => {
          let ai = JSON.parse(JSON.stringify(newMessageData.ai)); // 复制ai对象
          if (ai.responseCompleted == true) return; // 已经完成则不需要再调用接口了
          const itineraryId = globalDspId;  // 攻略id
          let journeyDemand = ""; // 出行卡片
          // 酒店卡片轮询的时候需要透传
          if (newMessageData.journeyDemand) { // 出行卡片
            journeyDemand = newMessageData.journeyDemand;
          }
          const resp = await requestMessageDetail(  // 请求消息详情接口
            newMessageData.chatId,  // 聊天id
            conversationId,  // 会话id
            itineraryId,  // 攻略id
            robotId,  // 机器人id
            journeyDemand  // 出行卡片
          );
          if (ai.responseCompleted == true) return;  // 已经完成则不需要再调用接口了
          if (resp.success) {
            this.$set(ai, 'text', resp.data.answer);  // 文本内容(输出)
            
            // console.log('返回结果类型', resp.data.answerType, resp.data.itineraryTheme, resp.data.status)
            ai.status = resp.data.status;  // 状态
            if (resp.data.status == 0) {  // 状态为0表示正在思考中
              ai.think = true;  // 思考中
            } else {
              ai.think = false;  // 思考结束
            }
            if (resp.data.status == 1 || resp.data.status == 0) { 
              // 还有内容没有返回， 需要重新请求
              setTimeout(() => {
                newMessageData.requestMessage();
              }, 1000);
            
              if (
                (resp.data.progress == 2) &&  // 进度为2并且还没开始显示内容则开始显示内容
                !ai.startProgress  
              ) {
                //开始显示进度
                ai.startProgress = true;
              }
            } else if (resp.data.status == 3) {
              // 返回结果都拿到了
              //直接结束进度
              ai.startProgress = false;
              const {
                articleList, // 文章列表，可能包含推荐文章或参考文章等信息
                poiList, // 兴趣点（Point of Interest）列表，通常包含景点、餐厅等信息
                productList, // 产品列表，可能包含商品、服务等相关产品信息
                dspInfo, // 可能是动态搜索广告（Dynamic Search Ads）相关信息，也可能是自定义的特定业务数据
                refArticleObj, // 参考文章对象，可能包含参考文章的详细信息和相关文本
                needPosition, // 是否需要获取定位信息的标识，true 表示需要，false 表示不需要
                recArticle, // 推荐文章，可能是根据用户行为或需求推荐的文章
                recHotel, // 推荐酒店信息，可能包含酒店的基本信息、推荐理由等
                journeyDemand, // 行程需求信息，可能包含用户对行程的各种要求
                nextScene, // 下一个场景信息，可能用于控制页面流程或 AI 交互的下一步动作
                sceneCode, // 场景代码，用于标识当前所处的业务场景或交互场景
                itineraryTheme, // 行程主题，可能用于描述行程的类型或风格
                recItinerary, // 推荐行程信息，可能包含行程的路线、景点安排等
                destId, // 目的地 ID，用于唯一标识一个目的地
                chatCardList, // 聊天卡片列表，可能包含各种类型的聊天卡片信息
                imageList, // 图片列表，可能包含与聊天内容相关的图片信息
                jumpApplet, // 是否跳转小程序的标识或小程序相关信息
                recProductQa, // 推荐的产品问答信息，可能包含产品的常见问题和答案
                customerService, // 客服相关信息，可能包含客服的联系方式或服务状态
                chatSynthesizeCard, // 聊天合成卡片信息，可能是将多种信息合成的卡片
                contractInfoList, // 合同信息列表，可能包含与业务相关的合同信息
                poiCard // 兴趣点卡片信息，可能包含单个兴趣点的详细卡片信息
              } = resp.data;
              ai.card = { articleList, poiList, productList, dsp: dspInfo ,sceneCode}; // 需要用卡片去显示的信息
              ai.needPosition = needPosition; //是否开启定位
              ai.appId = jumpApplet; // 是否跳转小程序
              ai.showGif = false;  // 展示gif，应该用于ai视频语音播报的
              if (resp.data.answerType == 1) {  // 文章
                ai.isShowDeatil = true;
                ai.dspId = resp.data.itineraryId;
                globalDspId = resp.data.itineraryId;
                ai.showGif = true;
              }
              if (resp.data.answerType == 3) {  // 图片
                ai.card.productList = dspInfo.productList;
                ai.showGif = true;
              }
              // 推荐攻略
              if (resp.data.answerType == 5) {  // 推荐攻略
                ai.card.recArticle = recArticle;
                ai.showGif = true;
              }
              // 参考攻略
              if (resp.data.answerType == 6) {  // 参考攻略
                ai.refArticleList = refArticleObj.articleList;
                ai.articleText = refArticleObj.articleText;
                ai.showGif = true;
              }
              if (resp.data.answerType == 4) {  // 卡片
                ai.card.recHotel = {
                  conversationId: newMessageData.conversationId,
                  ...recHotel};
                  ai.card.journeyDemand = journeyDemand;
                  ai.isHotelJourneyDemand = true;
                  ai.showGif = true;
              }
              globalPreSceneCode = sceneCode;
              globalNextScene = nextScene;
              if (resp.data.answerType == 7) {  // 餐馆卡片
                //展示餐馆卡片
                ai.showRecRestaurant = true;
                ai.card.recRestaurantData = {
                  conversationId: newMessageData.conversationId,
                  ...resp.data.recRestaurant,
                };
                ai.showGif = true;
              }
              if (resp.data.answerType == 8) {  // 商场卡片
                //展示商场卡片
                ai.showMarket = true;
                ai.card.marketData = {
                  conversationId: newMessageData.conversationId,
                  ...resp.data.recMarket,
                };
                ai.showGif = true;
              }
              if (resp.data.itineraryTheme) {  // 主题卡片
                // 展示偏好填写
                ai.showItineraryTheme = true;
                ai.card.itineraryTheme = itineraryTheme;
                ai.showGif = true;
              }
              if (resp.data.recItinerary) {  // 行程卡片
                // 参考行程
                // this.setRecItinerary()
                ai.showRecItinerary = true;
                ai.card.recItinerary = recItinerary;
                ai.showGif = true;
              }
              if (resp.data.destId) {  // 目的地
                //显示是否切换目的地
                ai.showChangeDest = true;
                ai.card.destId = destId;
              }
              if (resp.data.recPoi) {  // 推荐景点
                //显示热门推荐
                ai.showRecPoi = true;
                ai.card.recPoiData = resp.data.recPoi;
                ai.showGif = true;
              }
              if (resp.data.articleSummary) {  // 攻略
                //攻略小报
                ai.showRead = true;
                ai.card.readData = resp.data.articleSummary;
                ai.showGif = true;
              }
              if (resp.data.articleAssistantUrl) {  // 秒读助手
                //秒读助手
                ai.showarticleAssistantUrl = true;
                ai.card.articleAssistantUrl = resp.data.articleAssistantUrl;
                ai.showGif = true;
              }
              if (resp.data.itineraryCard) {  
                //新行程卡片
                ai.itineraryCard = resp.data.itineraryCard;
                ai.showGif = true;
              }
              if (resp.data.graphicItineraryCard) {
                //新行程卡片
                ai.graphicItineraryCard = resp.data.graphicItineraryCard;
                ai.showGif = true;
              }
      
              // 酒店偏好卡片
              if (resp.data.chatCardList.length > 0 && resp.data.chatCardList[0].type == 301) {
                ai.showHotelPreference = true
                ai.card.hotelPreference = chatCardList[0].args
              }
              // 酒店对比卡片
              if (resp.data.chatCardList.length > 0 && resp.data.chatCardList[0].type == 302) {
                ai.showHotelPriceParity = true
                ai.card.hotelPriceParity = chatCardList[0].args
              }
              // 酒店对比卡片
              if (resp.data.chatCardList.length > 0 && resp.data.chatCardList[0].type == 303 ) {
                ai.card.chatCardList = chatCardList
              }
              // 纯图
              if (resp.data.imageList) {
                ai.card.imageList = imageList
              }
              if (resp.data.chatCardList.length > 0 ) { // 老卡片
                ai.showCardList = true
                ai.card.chatCardList = chatCardList
              }
              // 合同卡片
              if (resp.data.contractInfoList && resp.data.contractInfoList.length > 0) {
                ai.showContractCard = true
                ai.card.contractInfoList = contractInfoList
              }
              // 商品详情跳ai
              if(resp.data.recProductQa){
                ai.card.recProductQa = recProductQa
                ai.recProductQa = recProductQa
                if(resp.data.recProductQa.title) {
                  topHomePageArr.splice(0,1,recProductQa)
                }
              }
              // 客服卡片
              if(resp.data.chatSynthesizeCard){
                ai.responseCompleted = true
                ai.card.chatSynthesizeCard = chatSynthesizeCard
              }
              // 兴趣点卡片
              if (poiCard) {
                ai.card.poiCard = poiCard
              }
              // 建议列表
              ai.suggestActions = resp.data.suggestActions;
              ai.sceneCode = sceneCode // 场景代码
              ai.customerService = customerService // 客服
              ai.responseCompleted = true;  // 回答完成
              newMessageData.pollFina();
              console.log('aiMessage', ai)
              // 命中黑名单和error ，直接替换文本
            } else if (resp.data.status == 2 || resp.data.status == -1) {
              ai.startProgress = false; // 开始进度关闭
              ai.isResetText = true; // 重置文本
              newMessageData.pollFina();
            } else {
              ai.startProgress = false; // 开始进度关闭
              ai.responseCompleted = true;  // 回答完成
              newMessageData.pollFina();
            }
      
            // 只有一次
            // if(sendTextObj.needSendStatus) {
            //   sendTextObj.needSendStatus = false
            // }
          } else {
            if (newMessageData.numberOfRetries >= maximumNumberOfRetries) { // 重试次数达到上限
              ai.responseCompleted = true;  // 回答完成
              newMessageData.pollFina();
            } else {
              newMessageData.numberOfRetries++; // 重试次数加1
              newMessageData.requestMessage(); // 重新请求
            }
          }
          newMessageData.ai = ai
        };
        newMessageData.startPolling = async () => { // 轮询接口
        newMessageData.pollAnswer = true;  // 轮询中
        newMessageData.requestMessage(); // 重新请求
        };
        newMessageData.pollFina = () => {
          const ai = JSON.parse(JSON.stringify(newMessageData.ai)); // 复制ai对象
          // ai 回答完成
          if(ai.text == '管家正在思考中...'){
            // 用户手动暂停
            ai.text = '好的，我先不回答了，有需要的话，请稍后再问我。'
          }
          ai.responseCompleted = true;  // 回答完成
          newMessageData.ai = ai
          globalIsPollStatus = true // 轮询状态
        };
        return newMessageData
      },
      takePhoneChange() { // 拍摄照片按钮点击事件
        // if (!this.$isLogin()) { // yuanbin 2024-05-16 16:18:28  登录校验先注释掉
        //   return;
        // }
        uni.chooseMedia({ // 调用手机拍摄功能或者从相册选择照片
          count: 1, // 最多选择1张照片
          mediaType:['image'],  // 只允许选择图片
          success: async (success) => {
            this.sendStatus = true;
            this.picUrlStatus = 'loading';
            this.onScrollToBottom();
            // 图片上传
            let res = await newUpload(
              { tempFilePath: success.tempFiles[0].tempFilePath },
              "vtrip-media",
              ""
            );
            // 如果上传成功
            if (res) {
              // 图片上传到ai校验
              this.$aiRequest({
                url: '/ai/aihub/chat/pic/check',
                method: 'POST',
                params: {picUrl: res}
              }).then(result => {
                if (result.data) {
                  this.picUrl = res;
                  this.picUrlStatus = '';
                  this.sendAiMessage();
                } else {
                  uni.showToast({
                    icon: 'none',
                    title: '提示: 您发送的内容含违禁图像，请更换图片后发送',
                    duration: 5000,
                  })
                  this.picUrlStatus = 'error';
                  this.sendStatus = false;
                }
              })
            } else {
              this.sendStatus = false;
            }
          },
        })
      },
      // 回到首页
      toHome() {
        if (uni.getStorageSync("cardType")) {
          // 跳出页面时清除商品卡片信息
          uni.removeStorageSync("cardType");
          this.signOutService();
        }
        uni.navigateTo({
          url: '/pages/index/index'
        })
      },
      // 转为对象
      parseQueryString(queryString) {
        // 去除开头的问号（如果有）
        if (queryString.startsWith('?')) {
          queryString = queryString.substring(1);
        }
  
        // 分割字符串为键值对数组
        var pairs = queryString.split('&');
  
        // 创建结果对象
        var result = {};
  
        // 遍历键值对数组，将每个键值对拆分为键和值，并存储到结果对象中
        pairs.forEach(function(pair) {
          var keyValue = pair.split('=');
          var key = decodeURIComponent(keyValue[0]);
          var value = decodeURIComponent(keyValue[1]);
          result[key] = value;
        });
  
        return result;
      },
      // ai视频切换
      changeGifIndex({code,type,timeOut,index}) { // code  展示地址个GIF，type  展示后是否切换动画，timeOut  延时多少毫秒后切换,index 需要切换成第几张
        clearTimeout(this.gifTimeout)
        this.gifTimeout = null
        this.aiGifIndex = code;
        if (type) {
          this.gifTimeout = setTimeout(() => {
            this.aiGifIndex = index;
          }, timeOut);
        }
      },
      changeDest() {
        console.log('打开了目的地---------+++++++++++++', this.$refs)
        if (!this.showDest) {
          this.$refs.maskDest.open();
          this.$refs.destBox.getDestItem()
          this.navIndex = 100;
        } else {
          this.$refs.maskDest.close();
          this.navIndex = 0;
        }
    
        this.showDest = !this.showDest;
      },
      //目的地选择，获取是初始化的显示目的地
      async destClick(item,code) {
        this.navIndex = 0;
        let destItem = JSON.parse(JSON.stringify(item));
        console.log('执行了...54555555555555555555555')
        this.getAiIconFun(destItem.destinationId)
        destItem.code = false
        uni.setStorageSync("changeDest", 0);
        uni.setStorageSync("aiDestItem", destItem);
        uni.setStorageSync("destItem", destItem);
        this.aiDestItem = destItem;
        this.$refs.maskDest.close();
        this.showDest = false;
        this.$refs.destBox.setDest(this.aiDestItem);
        console.log('目的地选择', item)
        this.getMapPreview(destItem.destinationId)
        if(item.code){ //手动切换
          //切换目的地重新创建会话
          console.log('切换目的地，..............')
          globalDspId = null
          this.createChat();
          if(this.messageData.datas.length< 1) return
          let len = this.messageData.datas.length -1
          this.$set(this.messageData.datas[len].ai, 'showNewDialogue', true)
          this.clearSuggestActions()
          this.topProductArr = []
          topHomePageArr = []
          uni.removeStorageSync('cardType')
          setTimeout(()=>{
            this.suggestActions = []
          },500)
          this.guidingSuggestActions(1)
          if (code === 'questionChange') {// 切换目的地，重新发起上一次提问
            const question = uni.getStorageSync('chatQuestion');
            this.sendAiMessage("", "", question);
          }
          return
        }
        console.log('刷新题词说话', uni.getStorageSync("askQuestion") )
        if(code === 'init') {
          await this.createChat('init');
        }
        if (!uni.getStorageSync("askQuestion")) {
          // 获取题词会创建会话Id
          await this.refreshTips();
        }
  
      },
      clearSuggestActions(){
        for(let i=0;i<this.messageData.datas.length;i++){
          if(this.messageData.datas[i].ai){
            this.$set(this.messageData.datas[i].ai, 'suggestActions', [])
          }
        }
      },
      sureClick(params) {
        this.recordStaus = false;
        globalNextScene = params.fixedSceneCode
        journeyPreference = params;
        let allTxtArr = []
        for(var i=0;i<params.journeyTopics.length;i++){
          allTxtArr.push(params.journeyTopics[i]) 
        }
        if(params.totalDaysNumber){
          allTxtArr.push(params.totalDaysNumber + "天")
        }
        for(var i=0;i<params.poiList.length;i++){
          allTxtArr.push(params.poiList[i].cardKey) 
        }
        if (params?.travellerNum) {
          if (params?.travellerNum.adult * 1 > 0) {
            allTxtArr.push("成人" + params.travellerNum.adult);
          }
          if (params?.travellerNum.children * 1 > 0) {
            allTxtArr.push("儿童" + params.travellerNum.children);
          }
          if (params?.travellerNum.elder * 1 > 0) {
            allTxtArr.push("老人" + params.travellerNum.elder);
          }
        }
        this.input = allTxtArr.join(",");
        this.sendAiMessage();
      },
      sureClickCall(data) {
        console.log('sureClick', data);
        //卡片点击回调
        this.recordStaus = false;
        if ((data.type == 31)) {
          //点击热门景点推荐回调
          let arr = [];
          data.favoritePoiList.map((item) => {
            arr.push(item.poiName);
          });
          favoritePoiList = data.favoritePoiList;
          let str = arr.join(",");
          this.input = str;
          this.sendAiMessage();
        }
        if(data.type == 'aiPhoto'){
          this.askQuestion({
            type: 1,
            txt:data.txt,
          })
        }
        if(data.type == 'actions'){ //卡片推荐问题
          userBehaviorDate = data
          userBehaviorDate.triggerType = data.triggerType ?  data.triggerType : 6
          if (data.fixedSceneCode) {
            globalNextScene = data.fixedSceneCode
            journeyPreference = {wantInfoList: { poiId: data.poiId }}
          }
          this.askQuestion({
            type: data.type,
            txt:data.txt,
          })
        }
        if(data.type == 'compare'){ // 酒店比价回调
          userBehaviorDate.triggerType = 4
          userBehaviorDate.buttonType = 9
          this.sendAiMessage(true)
          // this.askQuestion({
          //   type: 1,
          //   txt:data.txt,
          // })
        }
        if(data.type === 'text'){
          this.askQuestion({
            type: data.type,
            txt:data.text,
          })
        }
      },
      gotoOrderDetail(orderId) {
        this.$navTo(
          "/packageApp/pages/orderCode/ordercode",
          { orderId },
          "navigateTo"
        );
      },
      ///支付事件监听回调
      payMess(obj) {
        let option = {
          ...obj,
        };
        if (!option.itineraryPlanId) {
          option.itineraryPlanId = "";
        }
        if (!option.skuId) {
          option.skuId = "";
        }
        const chatMessage = this.ChatMessage(
          "",
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          "",
          true,
          this.dialogueModelAvatar,
          {},
          this.robotId
        );
        this.messageData.datas.push(chatMessage)
        this.inMessageTips = [];
        chatMessage.ai.isShowMessage = true;
        queryCardTemplate(4, option.itineraryPlanId, option.skuId)
          .then((resp) => {
            if (resp.data) {
              chatMessage.ai.text = resp.data.content || "";
              chatMessage.ai.orderId = obj.orderId;
              // sendTextObj.needSendStatus = true
              // globalNextScene = 18;
            }
            chatMessage.answered = true;
            this.sendStatus = false;
            this.onScrollToBottom();
          })
          .catch((error) => {
            this.changeGifIndex({ //失败
              code:4,
              type:true,
              timeOut:2300,
              index:1
            })
            chatMessage.ai.text = this.errorText[Math.floor(Math.random() * 4)];
            chatMessage.answered = true;
            this.onScrollToBottom();
          });
      },
      // 编辑行程
      editTripCardInfo(data) {
        let obj = {};
        let that = this;
        tripDetail({
          itineraryPlanId: data.itineraryPlanId,
        }).then((inresp) => {
  
          let tripCardInfo = inresp.data;
          obj.ai = {};
          obj.ai.card = { tripCardInfo };
          obj.ai.sell = data.sell;
          this.$nextTick(() => {
            that.messageData.datas.splice(data.meIndex, 1, obj);
            that.$forceUpdate();
          });
        });
      },
      // 切换攻略
      async handleSwiperChange(e) {
        if(e.detail.source !== "touch") return 
        this.isShowStrategyCard = false;
        this.swiperIndex = e.detail.current;
        let len = this.cardList.length;
        if (this.swiperIndex >= len - 2) {
          // 防止重复请求
          if(this.swiperRequestLoading) return
          this.swiperRequestLoading = true
          // 最后一张，请求数据
          let res = await queryPageRecommend({
            destId: this.aiDestItem.destinationId,
            conversationId: this.conversationId,
            articleIdList: this.cardList.map((nitem) => nitem.articleId),
          });
          // this.cardList.push(res.data)
          let artiArray = res.data.articleIdList.slice(0,3);
          // 应该是通过对应id获取指定攻略， 获取所有攻略存到cardList中
          const promises = artiArray.map((value) =>
            this.requestStrategyList(value)
          );
          const responses = await Promise.all(promises);
          // 按照请求顺序返回响应结果
          this.swiperRequestLoading = false
          if(responses.length) {
            this.$nextTick(()=>{
              this.cardList.push(...responses);
            })
            // let imgList = this.cardList.map((val) => val.coverImageUrl);
            // this.preloadImages(imgList);
          }
          // this.isShowCard = true;
        }
        // 获取当前下标下攻略的详情？
        this.$refs.strategyDeatail[e.detail.current].getAbout(
          this.cardList[e.detail.current].poiIdList
        );
      },
      onTouchStart(event) {
        this.startY = event.touches[0].clientY;
      },
      onTouchMoveCard(event) {
        this.currentY = event.touches[0].clientY;
      },
      handleTouchEnd(event) {
        let deltaY = this.startY - this.currentY;
        if (deltaY > 60 && this.currentY != 0) {
          // 手指向上滑动，执行需要的操作
          let activeIndex = this.swiperIndex;
          this.cardList[activeIndex].sourceCode;
          let obj = this.cardList[activeIndex];
          if (obj.sourceCode != 0) {
            uni.navigateTo({
              url: '/ai/pages/notedetails/notedetails?articleId=' + obj.articleId
            })
          } else {
            uni.navigateTo({
              url: '/ai/pages/notedetails/notedetails?articleId=' + obj.articleId
            })
          }
        }
      },
      async getTemplateCard(type) {
        this.recordStaus = false;
        const question = "";
        const speechUrl = "";
        const conversationId = "";
        const piolet = true;
        this.input = "";
        const chatMessage = this.ChatMessage(
          question,
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          this.speechUrl,
          piolet,
          this.dialogueModelAvatar,
          {},
          this.robotId
        );
        this.messageData.datas.push(chatMessage)
        this.inMessageTips = [];
        chatMessage.ai.isShowMessage = type == 7 ? true : false;
        queryCardTemplate(type)
          .then(async (resp) => {
            if (resp.data) {
              if (type == 7) {
                chatMessage.ai.text = resp.data.content || "";
                globalNextScene = 21;
              } else if (type == 8) {
                globalNextScene = 42;
                sendTextObj.usertext = resp.data.content;
                this.input = resp.data.content;
                await this.sendAiMessage();
              }
              chatMessage.answered = true;
              this.sendStatus = false;
              this.onScrollToBottom();
            }
          })
          .catch((error) => {
            this.changeGifIndex({ //失败
              code:4,
              type:true,
              timeOut:2470,
              index:1
            })
            chatMessage.ai.text = this.errorText[Math.floor(Math.random() * 4)];
            chatMessage.answered = true;
            this.onScrollToBottom();
          });
      },
      async getTemplateDestCard(obj) {
        const question = "";
        const speechUrl = "";
        const conversationId = "";
        const piolet = true;
        this.input = "";
        const chatMessage = this.ChatMessage(
          question,
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          this.speechUrl,
          piolet,
          this.dialogueModelAvatar,
          {},
          this.robotId
        );
        this.messageData.datas.push(chatMessage)
        this.inMessageTips = [];
        chatMessage.showChangeTxt = false;
        chatMessage.changetxt = "";
        await queryCardTemplateDest(obj.parasm)
          .then((res) => {
            if (res.data) {
              chatMessage.ai.text = res.data.content || "";
              chatMessage.answered = true;
              this.sendStatus = false;
              this.onScrollToBottom();
            }
          })
          .catch((error) => {
            this.changeGifIndex({ //失败
              code:4,
              type:true,
              timeOut:2470,
              index:1
            })
            chatMessage.ai.text = this.errorText[Math.floor(Math.random() * 4)];
            chatMessage.answered = true;
            this.onScrollToBottom();
          });
      },
      handClose(type) {
        this.startY = 0;
        this.currentY = 0;
        this.swiperIndex = 0;
        this.isShowStrategyCard = false;
        this.isShowCard = false;
        this.$refs.strategy.close();
        if (type) {
          this.liveList = [this.cardList[this.swiperIndex].articleId];
          this.getTemplateCard(8);
          return;
        }
        this.cardList = [];
        if (this.liveList.length > 0) {
          // 机器人根据用户喜欢 的攻略召回
          this.getTemplateCard(7);
        }
      },
      async generalUUID(articleId, index) {
        let that = this;
        // 攻略卡片弹窗对应摘要列表下标指向的内容先清空
        that.$set(that.loopAnswerList, that.swiperIndex, "");
        // 攻略卡片翻页接口， 用于获取下一页攻略内容
        let res = await queryUserSummary({
          articleId: articleId,
          conversationId: this.conversationId,
        });
        // 获取新攻略的uuid，用于轮询
        let uuid = res.data.uuid;
        this.loopArticleLoopAnswer(uuid, index);
      },
      async loopArticleLoopAnswer(uuid, index) {
        let that = this;
        // 通过uuid 查询对应攻略卡片的摘要信息
        let resTwo = await requestArticleLoopAnswer(uuid);
        if (resTwo.success) {
          // that.loopAnswerList[that.swiperIndex].loopAnswerText = resTwo.data.answer
          // 把上面清空的那个下标下内容重新赋值
          that.$set(that.loopAnswerList, that.swiperIndex, resTwo.data.answer);
          // 强制刷新
          that.$forceUpdate();
          // 如果状态为1，并且当前下标等于轮询的下标，继续轮询（status == 1 应该是指 没有结束的意思）
          if (resTwo.data.status == 1 && index == that.swiperIndex) {
            setTimeout(() => {
              that.loopArticleLoopAnswer(uuid, index);
            }, 800);
          }
        }
      },
      // 攻略卡片点击事件(换一篇，查看详情和收藏按钮点击事件)
      async handStrategy(index) {
        // 关闭攻略卡片弹窗
        this.isShowStrategyCard = false;
        // 强制刷新
        this.$forceUpdate();
        // 当前攻略卡片的下标
        let activeIndex = this.swiperIndex;
        // 切换下一页攻略卡片
        if (index == 0) {
          this.scaleChange = true;
          setTimeout(() => {
            this.scaleChange = false;
          }, 500);
          // 如果还有下一页
          if (this.swiperIndex < this.cardList.length - 1) {
            // 这里会触发上面watch的监听回调，会重新获取攻略卡片的摘要信息
            this.swiperIndex++;
          } else {
            uni.showToast({
              icon: "none",
              title: "没有更多了～",
              duration: 3000,
            });
            return;
          }
        } else if (index === 1) {
           // 查看详情按钮点击
          this.cardList[activeIndex].sourceCode;
          let obj = this.cardList[activeIndex];
          // 都是跳转到一个页面，只是有一个会关闭弹窗？
          if (obj.sourceCode != 0) {
            uni.navigateTo({
              url: '/ai/pages/notedetails/notedetails?articleId=' + obj.articleId
            })
            this.isShowStrategyCard = false;
          } else {
            uni.navigateTo({
              url: '/ai/pages/notedetails/notedetails?articleId=' + obj.articleId
            })
          }
        } else if (index === 2) {
          // 收藏按钮点击
          this.isShowD = true;
          this.scaleCollect = true;
          setTimeout(() => {
            this.scaleCollect = false;
          }, 500);
          let that = this;
          that.liveList.push(this.cardList[activeIndex].articleId);
          that.liveList = [...new Set(that.liveList)];
          let item = this.cardList[activeIndex];
          if (item.favorite) {
            //取消收藏
            let params = {
              articleId: item.articleId,
            };
            let res = await this.$aiRequest({
              url: "/ai/aihub/article/cancelCollecting",
              method: "POST",
              params,
            });
            if (res.success) {
              this.isShowStrategyCard = false;
              this.cardList[activeIndex].favorite = false;
            }
          } else {
            //收藏
            let params = {
              articleId: item.articleId,
            };
            let res = await this.$aiRequest({
              url: "/ai/aihub/article/collect",
              method: "POST",
              params,
            });
            if (res.success) {
              this.showTispFun(item.articleId)
              this.cardList[activeIndex].favorite = true;
            }
          }
          setTimeout(function () {
            that.isShowD = false;
            // 强制刷新
            that.$forceUpdate();
          }, 1400);
        }
      },
      //是否展示收藏tips
      async showTispFun(articleId) {
        let params = {
          articleIdList: [articleId],
          destId: uni.getStorageSync("aiDestItem").destinationId,
        };
        // 通过接口判断是否显示攻略卡片下面爱好规划路线
        let res = await this.$aiRequest({
          url: "/ai/aihub/showArticle2Itinerary",
          method: "POST",
          params,
        });
        if (res.data) {
          this.isShowStrategyCard = true;
        }else{
          this.isShowStrategyCard = false;
        }
      },
      // 点击消息结果里面的攻略卡片图片（左上角显示攻略的图片），跳转攻略详情页面
      async onStrategyClick(obj) {
        // this.isShowStrategyCard = false;
        let { list, item, index } = obj;
        // let articleList = list.map(articleItem => {
        //   return articleItem.articleId
        // })
        // uni.setStorageSync('articleList', articleList)
        // uni.removeStorageSync('articleList')
        uni.navigateTo({
          url: '/ai/pages/aiSecretDetail/index?articleId=' + item.articleId + '&hiddenChange=true'
        })
        
      },
      // 攻略卡片的轮询获取
      requestStrategyList(value) {
        return new Promise(async (resolve, reject) => {
          // 发送请求，并在得到响应后调用 resolve 方法
          let res = await queryArticleDetail({ articleId: value });
          resolve(res.data);
        });
      },
      onKeyboardHeightChange(res) {
        if (res.height > 100) {
          let height = res.height + 260;
          // 初始200是因为软键盘回调有延时，为了减少闪动
          this.aiBottomY = 0;
          if (this.isIos) {
            this.isHide = true
            setTimeout(()=>{
              this.isHide = false
            },270)
            this.aiBottomY = height - 20;
            this.KeyoardHeight = res.height - 75
            this.onScrollToBottom();
          } else {
            this.KeyoardHeight = res.height - 60
            this.aiBottomY = height;
          }
           // 只有输入框有字才需要重新调起
          if (this.input.length) {
            this.handleInput()
          }
        } else {
          console.log("进来了this.aiBottomY")
          this.showKeyWord = false;
          this.showBottom = false
          this.aiBottomY = 0;
          this.KeyoardHeight = res.height
        }
        
        this.onScrollToBottom();
        this.$forceUpdate();
  
      },
      // 获取手机号并且登陆
      getPhoneNumber(e) {
        console.log("获取了手机code", e);
        let that = this;
        //获取code发送到后台获取手机号
        if (e.detail.code) {
          that.getUserInfoAction(e.detail.code);
        } else {
          this.$refs.loginBox.close();
          uni.showToast({
            title: "拒绝授权将不能往下操作",
            icon: "none",
          });
        }
      },
      // 登陆
      getUserInfoAction(phoneCode) {
        let that = this;
        this.$refs.loginBox.close();
        uni.login({
          success: function (res) {
            that
              .$aiRequest({
                url: `/login/applet`,
                method: "POST",
                header: {
                  "Content-Type": "application/json",
                },
                params: {
                  phoneCode: phoneCode, //手机号code
                  loginCode: res.code, //登录code
                },
              })
              .then((res) => {
                if (res.success) {
                    //没有多个账号直接登录
                    that.$getUserInfo(res, that.options, 1);
                }
              });
          },
        });
      },
      // 解决软键盘遮挡输入框的问题
      focusInput() {
        // if(!uni.getStorageSync('Authentication')){
        //   // 没有登录的的情况下需要先登录一下
        //   this.$refs.loginBox.open()
        //   return;
        // }
        globalIsPollStatus = false
        // if (!this.$isLogin()) { // yuanbin 2024-05-16 16:18:28  登录校验先注释掉
        //   return;
        // }
        const that = this;
        // that.isAiShow = false;
        // setTimeout(()=>{ that.isAiShow = true}, 70)
        const systemInfo = uni.getSystemInfoSync();
        let isDevtools = systemInfo.platform === "devtools";
        let isIOSWithSafeArea =
          systemInfo.platform.indexOf("ios") !== -1 &&
          systemInfo.safeAreaInsets.bottom > 0;
        console.log(
          "是否在微信开发者工具环境中：",
          isDevtools,
          isIOSWithSafeArea,
          systemInfo.safeAreaInsets.bottom > 0
        );
        if (!isDevtools && isIOSWithSafeArea) {
          setTimeout(() => {
            that.focusStatus = true;
            console.log('重新聚焦。。。。。。。。', this.aiBottomY)
          }, 500);
        }
      },
      blurInput() {
        globalIsPollStatus = true
        this.focusStatus = false;
        this.showKeyWord = false;
        if (this.input.length < 1 && !this.recordStaus) {
          this.clickTxt = false;
        }
        this.aiBottomY = 0
      },
      // 弹出行程攻略， 行程纲要弹框
      showPopup(options) {
        console.log(options.dspId);
        this.selectedDspId = options.dspId;
        // if (options.type == 1) {
        //   this.getGeneral(options.dspId, false, options.breakTheIceStatus); //获取总览 半屏
        // } else if (options.type == 2) {
          // this.getDspInfo(options.dspId, options.dspStatus); //获取整屏

          uni.navigateTo({
            url: '/ai/pages/aiDSPDetail/aiDSPDetail?dspId=' + options.dspId + '&isBack=1&isFormChat=true' + '&isShowBuy=' +options.showButton
          })
        // }
      },
      changeOpen(index) {
        this.infoData.dayNodeList[index].open =
          !this.infoData.dayNodeList[index].open;
      },
      //获取简介
      async getSummary(params) {
        let that = this;
        let res = await this.$aiRequest({
          url: "/ai/aihub/trip/summary",
          method: "POST",
          params,
        });
        if (res.success) {
          if (!res.data.isSummary) {
            setTimeout(() => {
              that.getSummary(params);
            }, 1000);
          } else {
            for (var i = 0; i < this.infoData.dayNodeList.length; i++) {
              if (this.infoData.dayNodeList[i].dayNum == res.data.dayNum) {
                this.infoData.dayNodeList[i].summary = res.data.summary;
                this.$forceUpdate();
              }
            }
          }
        }
      },
      // 获取数组里面最大值
      getMax(arr) {
        var max = arr[0];
        for (var i = 1; i < arr.length; i++) {
          var cur = arr[i];
          cur > max ? (max = cur) : null;
        }
        return max * 1;
      },
      // 获取数组里面最小值
      getMin(arr) {
        var min = arr[0];
  
        for (var i = 1; i < arr.length; i++) {
          var cur = arr[i];
          cur < min ? (min = cur) : null;
        }
        return min * 1;
      },
      // 计算坐标中心点
      findCenter(coords) {
        let totalLat = 0;
        let totalLng = 0;
  
        // 计算所有点的纬度和经度总和
        for (let i = 0; i < coords.length; i++) {
          totalLat += coords[i][0];
          totalLng += coords[i][1];
        }
  
        // 计算平均纬度和平均经度
        let avgLat = totalLat / coords.length;
        let avgLng = totalLng / coords.length;
  
        // 返回中心点的坐标
        return [avgLat, avgLng];
      },
      /// 机器人主动破冰问话
      robotSpeak(text) {
        const chatMessage = this.ChatMessage(
          "",
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          "",
          true,
          this.dialogueModelAvatar,
          {},
          this.robotId
        );
        this.messageData.datas.push(chatMessage)
        setTimeout(() => {
          chatMessage.ai.isShowMessage = true;
          chatMessage.ai.text = text || "";
          chatMessage.answered = true;
          this.sendStatus = false;
          this.onScrollToBottom();
        }, 200);
      },
      async commonMethod(valid, chatMessage, isPoll, resp) {
        if (valid) {
          this.sendStatus = true;
          chatMessage.chatId = resp.data.chatId;
          // 将chatId存起来
          // uni.setStorageSync("chatId", resp.data.chatId)
          if (resp.data.journeyDemand) {
            chatMessage.journeyDemand = resp.data.journeyDemand;
          }
          globalIsPollStatus = false
          chatMessage.ai.text = "";
          this.startPolling(chatMessage);
        } else {
          if (!isPoll) {
            globalIsPollStatus = true
          }
          if (resp.data.journeyDemand) {
            if (resp.data.showCard === 1) {
              chatMessage.ai.text = "请完善你的出行需求：";
              chatMessage.journeyDemand = resp.data.journeyDemand;
              return;
            }
  
            if (resp.data.showCard === 2) {
              // 根据需求信息去请求行程单卡片
              let textStr = "";
              let tempRes = await queryCardTemplate(1, globalDspId);
              this.$set(chatMessage.ai, "card", {});
              if (tempRes.data) {
                textStr = tempRes.data.content;
              }
              let cardRes = await this.getJonCardInfo(
                resp.data.journeyDemand
              );
              if (cardRes.data) {
                chatMessage.ai.text = textStr;
                const tripCardInfo = cardRes.data;
                chatMessage.ai.card = { tripCardInfo };
                chatMessage.ai.text = textStr;
                chatMessage.answered = true;
                chatMessage.journeyDemand = null;
                this.$forceUpdate();
                this.onScrollToBottom();
              }
            }
          }
          this.sendStatus = false;
        }
        if (globalNextScene == 17 && !chatMessage.ai.text) {
          chatMessage.ai.text = "请完善你的出行需求：";
        }
        chatMessage.user.text = resp.data.question;
        journeyPreference = "";
      },
      // 切换目的地缓存
      handleChangeDest(destId) {
        let destList = JSON.parse(uni.getStorageSync('aiDestList'))
        let aiDestItem = uni.getStorageSync('aiDestItem')
        for(var i=0;i<destList.length;i++){
          if(destId === destList[i].destinationId && destId != aiDestItem.destinationId){
            this.destClick({
              code:true,
              ...destList[i]
            })
            break;
          }
        }
      },
      // 获取数字人
      async getAiIconFun(destId) {
        let res = await getClothes(destId)
        console.log(res,'获取数字人')
        if (res.data) {
          this.aiGifList[3] = res.data.chatTypeGiF // 左手介绍
          this.aiGifList[1] = res.data.chatPage // 站立
          this.aiGifList[0] = res.data.helloGif // 打招呼
          this.aiGifList[2] = res.data.chatTypeGiF // 用于发送消息时显示一下
          this.chatTitle = res.data.chatTitleGiF
  
        }
      },
      // 轮询请求
      async pollSendAiMessage(userBehavior) {
        const question = "";
        const speechUrl = "";
  
        const piolet = true;
        const conversationId = this.conversationId;
        if (!conversationId) {
          console.log('轮询 ，但是没有会话ID..............')
          await this.createChat();
        }
        const chatMessage = this.ChatMessage(
          question,
          this.messageData.datas.length,
          conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          this.speechUrl,
          piolet,
          this.dialogueModelAvatar,
          {},
          this.robotId,
          this.picUrl
        );
        this.$set(this, 'topProductArr', topHomePageArr)
        this.$forceUpdate()
        this.inMessageTips = [];
        if (uni.getStorageSync('aiObj') && uni.getStorageSync('aiObj').destId) {
          const destId = uni.getStorageSync('aiObj').destId
          this.handleChangeDest(destId);
        }
        let options = {
          conversationId,
          itineraryId: globalDspId,
          robotId: this.robotId,
          fixedSceneCode: globalNextScene,
          destId: uni.getStorageSync("aiDestItem").destinationId,
        };
    
        options.latitude = uni.getStorageSync("location")
          ? uni.getStorageSync("location").latitude
          : "";
        options.longitude = uni.getStorageSync("location")
          ? uni.getStorageSync("location").longitude
          : "";
  
        /**
         * 
         */
        if(userBehavior) {
          options.chatType = 3;
          options.userBehavior = {
            // 触发类型 0=用户主动输入 1-无操作 2-点击卡片返回 4-点击按钮 5-重新进入小程序 6=点击提词	
            triggerType: globalTriggerType
          }
        }
        let isReStatus = false
        if (globalTriggerType != 1 ) {
          isReStatus = true
        }
        // 如果缓存有aiObj对象  就去缓存里面的场景值
        if(uni.getStorageSync('aiObj')){
          if (uni.getStorageSync('cardType')) {
            // this.isShowAiGif = false;  // yuanbin 20250509 目前需求不需要隐藏数字人
          }
          options.fixedSceneCode = uni.getStorageSync('aiObj').fixedSceneCode
          options.serviceRobot = uni.getStorageSync('aiObj')
          options.cardType = uni.getStorageSync('cardType')
          options.userBehavior={
            triggerType: 0
          }
        }
        if (!options.conversationId) {
          return;
        }
        sendMessage(options)
            .then(async (resp) => {
              uni.removeStorageSync('aiObj')
            // 深度交互，点赞和踩需要chatID给到服务端，所以需要在对话中保留chatID
            if(resp.data.chatId) {
              chatMessage.ai.chatId = resp.data.chatId
            }
  
            if(userBehavior && resp.data.answer && !resp.data.stream){
              setTimeout(() => {
                chatMessage.ai.text = resp.data.answer || "";
              }, 200);
              this.messageData.datas.push(chatMessage)
            }
            if (resp.data.stream){
              this.messageData.datas.push(chatMessage)
            }
            if (globalTriggerType != 1 && isReStatus ) {
              globalTriggerType = 1
            }
            if(resp.data.destId !== '-1'){ //如果返回目的地不等于-1 则表示需要自动切换
              const destId = resp.data.destId
              this.handleChangeDest(destId);
            }
            if(resp.data.suggestActions.length > 0){
              this.suggestActions = resp.data.suggestActions
              chatMessage.ai.suggestActions = resp.data.suggestActions;
            }
            if (resp.data.showCard !== 2) {
              chatMessage.ai.card = resp.data;
            }
            chatMessage.answered = true;
            const valid = resp.data.stream;
            this.speechUrl = "";
            // this.picUrl = "";
            // this.picUrlStatus = "";
            this.fixedSceneCode = null;
            favoritePoiList = [];
            journeyPreference = "";
            // console.log('resp', resp)
            // console.log('valid', valid)
            // 需要轮询
            this.commonMethod(valid, chatMessage, true, resp)
            // this.onScrollToBottom();
          })
          .catch((error) => {
            uni.removeStorageSync('aiObj')
            const that = this;
            that.commonCatch(chatMessage)
          });
      },
      commonCatch(chatMessage) {
        const that = this;
        that.sendStatus = false;
        this.changeGifIndex({ //失败
          code: 4,
          type: true,
          timeOut: 2470,
          index: 1
        })
        chatMessage.ai.text = that.errorText[Math.floor(Math.random() * 4)];
        chatMessage.answered = true;
      },
  
      //获取行程商品卡片
      async getDspProduct() {
        console.log(1111)
        const question = "";
        const speechUrl = "";
        const conversationId = "";
        const piolet = true;
        this.input = "";
        let textStr = "";
        let tempRes = await queryCardTemplate(1, globalDspId);
        if (tempRes.data) {
          textStr = tempRes.data.content;
        }
        const chatMessage = this.ChatMessage(
          question,
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          this.speechUrl,
          piolet,
          this.dialogueModelAvatar,
          {},
          this.robotId,
          this.picUrl
        );
        this.messageData.datas.push(chatMessage)
        this.inMessageTips = [];
        if (textStr) {
          chatMessage.ai.isShowMessage = true;
        } else {
          chatMessage.ai.isShowMessage = false;
        }
  
        let params = {
          itineraryId: globalDspId,
          conversationId: this.conversationId,
          destId: uni.getStorageSync("aiDestItem").destinationId
        };
        recItinerary(params)
          .then((res) => {
            uni.removeStorageSync('isFromDspDetail');
            if (res.data) {
              const tripCardInfo = res.data;
              chatMessage.ai.card = { tripCardInfo };
              chatMessage.ai.text = textStr;
              chatMessage.answered = true;
              // globalNextScene = 17
              this.onScrollToBottom();
            } else {
              chatMessage.ai.isShowMessage = false;
            }
          })
          .catch((error) => {
            this.changeGifIndex({ //失败
              code:4,
              type:true,
              timeOut:2470,
              index:1
            })
            chatMessage.ai.text = this.errorText[Math.floor(Math.random() * 4)];
            chatMessage.answered = true;
            chatMessage.ai.isShowMessage = false;
            this.onScrollToBottom();
          });
      },
      async closeDetail() {
        this.$refs.journeyDetailPop.close();
        // this.getDspProduct()
      },
      // 预加载图片
      preloadImages(list) {
        let urlList = [];
        if (list) {
          urlList = list;
        } else {
          urlList = this.imgUrls;
        }
        const promises = urlList.map((url) => {
          return new Promise((resolve, reject) => {
            uni.getImageInfo({
              src: url,
              success: (res) => {
                resolve(res);
              },
              fail: (err) => {
                reject(err);
              },
            });
          });
        });
  
        Promise.all(promises)
          .then((results) => {
            console.log("所有图片加载完成", results);
          })
          .catch((err) => {
            console.log("图片加载失败", err);
          });
      },
      // 获取行程卡片信息
      async getJonCardInfo(journeyDemand) {
        console.log('获取行程卡片信息')
        return new Promise((resolve, reject) => {
          let params = {
            itineraryId: globalDspId,
            journeyDemand,
            conversationId: this.conversationId,
            destId: uni.getStorageSync("aiDestItem").destinationId
          };
          recItinerary(params).then((res) => {
            if (res) {
              resolve(res);
            }
          });
        });
      },
      ///选择一个角色
      onpiolet(options) {
        this.robotId = options.id;
        this.dialogueModelAvatar = options.dialogueModelAvatar;
        this.robotObj = {
          voiceType: options.speechId, // 音色
          playbackRate: options.speechSpeed, // 语速
          timbre: options.timbre,
        };
        globalPlaybackRate = options.speechSpeed;
        if (this.isPolling) {
          this.pollFina();
        }
        // TODO: 调整 
        // 如果缓存有aiObj对象  就让轮询取缓存里面的场景值
        if(!uni.getStorageSync('aiObj')){
          this.sendAiMessage(true);
        } else {
          // 有的时候直接获取商品详情介绍
          this.pollSendAiMessage(true);
        }
       
      },
      // 上传到资源服务器，再调用chat
      async sendServe() {
        let res = await newUpload(
          { tempFilePath: this.voicePath },
          "vtrip-media",
          ""
        );
        this.speechUrl = res;
        this.sendAiMessage();
      },
      // 滑动事件
      onTouchMove(e) {
        const y = e.touches[0].clientY;
        if (
          y < this.clientY - 20
        ) {
          // 手指滑动到指定位置后触发事件
          this.isCancel = true;
        } else {
          this.isCancel = false;
        }
      },
      // 按住录音事件
      longpress() {
        // if (!this.$isLogin()) { // yuanbin 2024-05-16 16:18:28  登录校验先注释掉
        //   return;
        // }
        this.islongPress = true;
        // this.$refs.recordPopup.open();
        // 创建SelectorQuery实例
        setTimeout(() => {
          this.startRecord();
          const query = uni.createSelectorQuery().in(this);
          // 获取container元素的位置
          query
            .select(".talk_box")
            .boundingClientRect((res) => {
              this.clientX = res.left;
              this.clientY = res.top;
            })
            .exec();
        }, 100);
      },
      initData() {
        this.speechUrl = ""; // MP3地址
      },
      touchend(e) {
        //延时执行为了防止 click() 还未判断 islongPress 的值就被置为 fasle
        setTimeout(() => {
          this.islongPress = false;
          this.$refs.recordPopup.close();
          if (!this.isCancel) {
            this.stopRecord();
          } else {
            this.initData();
            this.stopRecord();
          }
        }, 200);
      },
      // 机器人切换
      changeIndex(e) {
        this.current = e.detail.current;
      },
      // 开始录音
      startRecord() {
        recorderManager.start({
          format: "mp3",
          duration: 59000,
        });
      },
      // 停止录音
      stopRecord() {
        recorderManager.stop();
      },
      // 切换输入或者语音
      onChangeLanguageType() {
        this.recordStaus = !this.recordStaus;
        // 第一次授权触发
        if (this.recordStaus) {
          let that = this;
          uni.authorize({
            scope: "scope.record",
            success(res) {
              console.log("录音授权成功");
            },
            fail(res) {
              console.log("录音授权失败111");
              uni.showModal({
                title: "提示",
                content: "您未授权录音，是否打开设置页面进行授权？",
                success(res) {
                  if (res.confirm) {
                    uni.openSetting({
                      success(res) {
                        if (res.authSetting["scope.record"]) {
                          console.log("录音授权成功");
                        } else {
                          console.log("录音授权失败111222");
                          that.recordStaus = false;
                        }
                      },
                    });
                  } else if (res.cancel) {
                    console.log("用户点击取消");
                    that.recordStaus = false;
                  }
                },
              });
            },
          });
        }
      },
      pogressSrc(index) {
        return `${this.baseCdnUrl}2023-06-22/jindutiao-${
          (index > 2 ? 0 : index) + 1
        }.png`;
      },
      ///滚动到底部
      onScrollToBottom:throttle(function(){
          setTimeout(() => { this.messageScrollIntoView = 'scroll-bottom-id' },10)
          setTimeout(() => { this.messageScrollIntoView = '' },200)
      }, 400),
      setup(code) {
  
        if(!code){
          this.createChat();
        }
        // this.closeJourneyInfoPop()
      },
      onClear() {
        if (this.messageData.datas?.length <= 0) return;
        this.pollFina();
        this.messageData.datas = []
        this.inMessageTips = [];
        this.rating = 0;
        this.conversationId = undefined;
        this.setup();
      },
      onClickTips(val) {
        this.input = val.question;
        this.recordStaus = false;
        if (this.isPolling) {
          this.pollFina();
        }
        this.sendAiMessage();
      },
      onClickEditJoun(val) {
        this.recordStaus = false;
        globalNextScene = 31;
        this.input = "修改行程";
        this.sendAiMessage();
        this.onScrollToBottom();
      },
      // 需求卡片确认选择
      async editItinerary(val) {
        journeyDemand = val;
        this.input =
          "出行日期：" +
          journeyDemand.journeyDemand.startDate +
          "；成人：" +
          (journeyDemand.journeyDemand.travellerNum.adult || 0) +
          "；儿童：" +
          (journeyDemand.journeyDemand.travellerNum.children || 0) +
          ";";
        this.sendAiMessage();
      },
      ///刷新提词、机器人角色
      async refreshTips(code) {
        return  new Promise(async (resolve, reject)=>{
          let params = {
            destId: this.aiDestItem.destinationId,
          };
          const resp = await requestTips(params);
          if (resp.success) {
            this.figureObjList = resp.data || [];
            if (this.figureObjList.length > 0) {
              let list = [];
              this.dialogueModelAvatar = this.figureObjList[0].dialogueModelAvatar;
              this.robotId = this.figureObjList[0].id;
              globalPlaybackRate = this.figureObjList[0].speechSpeed;
              this.robotObj = {
                voiceType: this.figureObjList[0].speechId, // 音色
                playbackRate: this.figureObjList[0].speechSpeed, // 语速
                timbre: this.figureObjList[0].timbre,
              };
              list = this.figureObjList.map((item) => {
                return item.dialogueModelAvatar;
              });
              this.preloadImages(list);
            }
            console.log(code, '[[[[[[[[[[[==========]]]]]]]]]]]')
            if (!code){ //如果有code 表示不用说话
              console.log('//如果有code 表示不用说话')
              await this.onpiolet(this.figureObjList[0]);
            } else {
              console.log('创建会话id2535')
              await this.createChat('init');
              
            }
            resolve()
          }
        })
      },
      async signOutService () {
        await this.createChat();
        let len = this.messageData.datas.length -1
        if(len >= 0){
          this.messageData.datas[len].ai.showNewChat = true
        }
        this.topProductArr = []
        topHomePageArr = []
      },
      ///创建一个新的会话id
      async createChat(code) {
        return new Promise(async (resolve, reject)=>{
          console.log(code,'[[[[[[]]]]]]', this.conversationId)
          // 防止多个地方并发触发，导致短时间产生多个conversationId
          if(code == 'init' && !!this.conversationId){
            console.log('已经由了，退出', this.conversationId)
            return
          }
          // 新建ai对话
          // 会返回回话ID，
          const resp = await newConversation({destId: uni.getStorageSync("aiDestItem").destinationId});
          if (resp.success) {
            if(code == 'init' && !!this.conversationId){
              console.log('返回结果时候已经由了，退出')
              return
            }
            this.conversationId = resp.data.conversationId;
            //缓存会话ID
            uni.setStorageSync('conversationId',this.conversationId)
            // 会话状态， 用于判断当前会话是否结束
            this.watermarkInfo.sourceCode = resp.data.sourceCode;
            // 水印（用于sl-watermark.vue 暂时不清楚具体作用）
            this.watermarkInfo.watermarking = resp.data.watermarking;
            globalDspId = null
            // console.log('缓存会话ID',  this.conversationId, resp)
            resolve()
          }else {
            reject()
          }
        })
      },
      ///发送按钮
      onButtonClick() {
        if(this.sendStatus){
          this.sendStatus = false
          this.pollFina()
          return
        }
        // yuanbin 暂时注释掉， 因为没有登录权限
        // if(!this.$isLogin()){
        //   return
        // }
        if (this.isPolling) {
          this.pollFina();
        } else {
          this.sendAiMessage();
        }
        clearInterval(this.gifTimer);
        this.gifTimer = null
        this.timeNum = 0
        this.changeGifIndex({
            code:1,
            type:false,
          }
        )
      },
      // 发送消息
      async sendAiMessage(piolet, robotId, chatQuestion) {
        if (typeof piolet == "object") {
          piolet = undefined;
        }
        if(globalIsPollStatus){
          globalIsPollStatus = false
        }
        const question = chatQuestion ? chatQuestion : this.input;
        const speechUrl = this.speechUrl;
        if (question) {
          // this.isShowAiGif = false;  // yuanbin 20250509 目前需求不需要隐藏数字人
        }
        if (!this.recordStaus && !this.picUrl && !piolet && (!userBehaviorDate.triggerType)) {
          if (!question || question.length <= 0 || question.trim() === "") {
            uni.showToast({
              icon: "none",
              title: "请先输入内容",
              duration: 3000,
            });
            return;
          }
        }
        // 如果在录音中并且录音地址为空，则不请求
        if (this.recordStaus && !speechUrl) {
          return;
        }
        let conversationId = this.conversationId;
        if (!this.conversationId) {
          // console.log('发送消息，但是没有会话ID..............')
          await this.createChat();
          conversationId = this.conversationId;
          // console.log('发送消息，但是没有会话ID,新建后..............',this.conversationId)
        }
        this.input = "";
        this.greyOut()
        const robotObj = { ...this.robotObj };
  
        const chatMessage = this.ChatMessage(
          question,
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          this.speechUrl,
          piolet,
          this.dialogueModelAvatar,
          robotObj,
          this.robotId,
          this.picUrl
        );
        this.messageData.datas.push(chatMessage)
        const ai = JSON.parse(JSON.stringify(chatMessage.ai));
        this.inMessageTips = [];
        this.clearSuggestActions();// 清空题词
        let options = {
          conversationId,
          itineraryId: globalDspId,
          robotId: this.robotId,
          fixedSceneCode: globalNextScene,
          destId: uni.getStorageSync("aiDestItem").destinationId,
          version: '1.1',
        };
        this.onScrollToBottom();
        options.latitude = uni.getStorageSync("location")
          ? uni.getStorageSync("location").latitude
          : "";
        options.longitude = uni.getStorageSync("location")
          ? uni.getStorageSync("location").longitude
          : "";
        if (piolet) {
          options.chatType = 3;
          options.fresh = uni.getStorageSync('fresh') ? false : true
          uni.setStorageSync('fresh',1)
          options.shareToken = this.optionsData.shareTokenId
          options.contractRecordId = this.optionsData.contractRecordId
        } else if (this.recordStaus) {
          options.chatType = 2;
          options.speechUrl = speechUrl;
        } else if (this.picUrl) {
          options.chatType = 4;
          options.picUrl = this.picUrl;
        } else {
          options.chatType = 1;
          options.question = question;
        }
  
        /**
         * 
         */
        if(userBehaviorDate.triggerType) {
          // options.question = '2024-01-10, 0-500, 500-1000, 尖沙咀',
          // options.chatType = 3;
          options.userBehavior = {
            //  按钮类型 1-分享酒店卡片-立即预订 2-分享酒店订单卡片-行程规划 3-分享酒店订单卡片-领取旅拍权益 4-分享门票订单卡片-查看凭证 5-分享门票订单卡片-酒店推荐 6-酒店偏好卡片-确认
            buttonType: userBehaviorDate.buttonType,
            hotelPreference: userBehaviorDate.hotelPreference,
            orderInfo: userBehaviorDate.orderId ? {
              orderId: userBehaviorDate.orderId
            } : '',
            // 触发类型 0=用户主动输入 1-无操作 2-点击卡片返回 4-点击按钮 5-重新进入小程序 6=点击提词	
            triggerType: userBehaviorDate.triggerType,
            aigcThemeId: userBehaviorDate.aigcThemeId ? userBehaviorDate.aigcThemeId : ''
          }
        }
        if(userBehaviorDate.articleId){ // 如果数据articleId  就要传
          options.articleId = userBehaviorDate.articleId
        }
        if (globalNextScene == 42) {
          options.articleIdList = this.liveList;
        }
        if (globalNextScene == 21) {
          options.articleIdList = this.liveList;
        }
        if (globalNextScene == 17) {
          options.fixedSceneCode = 17;
        }
        if (journeyPreference) {
          options.journeyPreference = journeyPreference;
        }
        if (favoritePoiList.length > 0) {
          //选择推荐景点
          options.favoritePoiList = favoritePoiList;
          options.fixedSceneCode = 3;
        }
        if(this.suggestActionsItem){
          options.suggestAction = this.suggestActionsItem
        }
        if (uni.getStorageSync('shareTokenId')) {
          // options.chatType = 3; // 小师妹要求去掉
          options.shareToken = this.optionsData.shareTokenId
        }
        if (uni.getStorageSync('cardType')) {
          options.cardType = uni.getStorageSync('cardType')
        }
        // console.log("this.optionsData.shareTokenId", options);
        if (!options.conversationId) {
          return;
        }
        sendMessage(options)
          .then(async (resp) => {
            // console.log('接收用户发送信息的返回AI结果', resp)
            setTimeout(() => {
              uni.removeStorageSync("shareTokenId");
            }, 600);
            userBehaviorDate = {}
            if(resp.data.destId !== '-1'){ //如果返回目的地不等于-1 则表示需要自动切换
              let destList = JSON.parse(uni.getStorageSync('aiDestList'))
              let aiDestItem = uni.getStorageSync('aiDestItem')
              for(var i=0;i<destList.length;i++){
                // console.log(destList[i])
                if(resp.data.destId === destList[i].destinationId && resp.data.destId != aiDestItem.destinationId){
                  this.destClick({
                    code:true,
                    ...destList[i]
                  })
                  break;
                }
              }
            }
            // 将提问存起来，当提问需要切换目的地时，重新发送这句话
            if (resp.data.question) {
              uni.setStorageSync('chatQuestion', resp.data.question)
            }
            // 深度交互，点赞和踩需要chatID给到服务端，所以需要在对话中保留chatID
            if(resp.data.chatId) {
              ai.chatId = resp.data.chatId
            }
            if(resp.data.guidingSuggestActions){
              this.actionList = resp.data?.welcomeCard?.cardList
            }
            if(resp.data.suggestActions.length > 0){
              this.suggestActions = resp.data.suggestActions
              ai.suggestActions = resp.data.suggestActions;
            }
            ai.text = resp.data.answer || "";
            if (resp.data.showCard !== 2) {
              ai.card = resp.data;
            }
            if(resp.data.wechatUrl){
              ai.card = resp.data;
            }
            if(resp.data.answerType === 100 && resp.data.chatSynthesizeCard){
             
              // chatMessage.ai.card.responseCompleted = true
              // chatMessage.ai.card.chatSynthesizeCard = chatSynthesizeCard
            }
            chatMessage.answered = true;
            this.$set(chatMessage, "ai", ai);
            const valid = resp.data.stream;
            this.speechUrl = "";
            this.picUrl = "";
            this.picUrlStatus = "";
            this.recordStaus = false;
            this.fixedSceneCode = null;
            favoritePoiList = [];
            journeyPreference = "";
            globalNextScene = ""
            // 需要轮询
            this.commonMethod(valid, chatMessage, false, resp)
            this.onScrollToBottom();
          })
          .catch((error) => {
            console.log('error', error)
            const that = this;
            setTimeout(() => {
              uni.removeStorageSync("shareTokenId");
            }, 600);
            that.commonCatch(chatMessage)
            that.onScrollToBottom();
            globalIsPollStatus = true
          });
      },
      async getProductQaData(message) {
        const resp = requestMessageDetail(message.chatId, message.conversationId)
      },
      //置灰按钮  
      greyOut(){
        let list = this.messageData.datas
        for(var i =0; i<list.length;i++){
          list[i].ai.clickable = false
        }
        this.messageData.datas = list
        this.$forceUpdate()
      },
      ///开始轮询
      startPolling(message) {
        this.pollingChatMessage = message;
        // console.log('开始轮询_____', this.pollingChatMessage)
        message.startPolling();
      },
      ///结束轮训
      pollFina() {
        this.pollingChatMessage.pollFina();
        this.pollingChatMessage = undefined;
        this.sendStatus = false;
        setTimeout(() => {
          this.onScrollToBottom()
        }, 1000);
      },
      onTextAreaHeightChange(obj) {
        this.inputOffsetTop = obj.currentTarget.offsetTop;
      },
      /**
       * 发送事件数据
       * @param {*} eventId 事件ID
       * @param {*} eventType 事件名
       * @param {*} spmCntSuffix 点位
       * @param {*} obj 业务参数
       */
      postEventData(eventId, eventType, spmCntSuffix, obj) {
        this.$spmFun(
          pointData,
          this.getEventObj(eventId, eventType, spmCntSuffix, obj)
        );
      },
      /**
       * 获取事件数据
       * @param {*} eventId 事件ID
       * @param {*} eventType 事件名
       * @param {*} spmCntSuffix 点位
       * @param {*} obj 业务参数
       */
      getEventObj(eventId, eventType, spmCntSuffix, obj) {
        return {
          event_id: eventId,
          event_type: eventType,
          spm_cnt: `${pointData.platform}.ChatAi.${spmCntSuffix}`,
          spm_pre: this.parentSpm.pre,
          spm_ref: this.parentSpm.ref,
          open_time: this.enterTime.getTime(),
          args: {
            ...obj,
          },
        };
      },
      progressBar(total) {
        let percent = 0;
        let bar = "";
        const intervalId = setInterval(() => {
          percent++;
          bar = "#".repeat(Math.floor(percent / 10));
          if (percent === total) {
            clearInterval(intervalId);
          }
        }, 1000);
      },
      // 获取出行提醒
      async upcomingTravel() {
        if (this.isShowItineraryId) return;
        // TODO: 不要把以下代码放到请求回调里面，不然答案无法显示
        const question = "";
        const speechUrl = "";
        const conversationId = "";
        const piolet = true;
        this.input = "";
        const chatMessage = this.ChatMessage(
          question,
          this.messageData.datas.length,
          this.conversationId,
          "",
          this.recordStaus,
          this.voiceTime,
          this.speechUrl,
          piolet,
          this.dialogueModelAvatar,
          {},
          this.robotId
        );
        chatMessage.ai.isShowMessage = false;
        chatMessage.ai.card = {};
  
        //请求数据
        getUpcomingTravel()
          .then((resp) => {
            if (resp.success && resp.data) {
              this.inMessageTips = [];
              let data = resp.data?.[0] || {};
              setTimeout(() => {
                chatMessage.ai.text = data.openingPhrase || "";
              }, 200);
              chatMessage.ai.card.tipsInfo = data;
              chatMessage.answered = true;
              this.isShowItineraryId = data.itineraryId;
              chatMessage.ai.isShowMessage = true;
              this.sendStatus = false;
              this.messageData.datas.push(chatMessage)
              // this.$forceUpdate()
              this.onScrollToBottom();
            } else {
            }
          })
          .catch((error) => {
            this.changeGifIndex({ //失败
              code:4,
              type:true,
              timeOut:2470,
              index:1
            })
            chatMessage.ai.text = this.errorText[Math.floor(Math.random() * 4)];
            chatMessage.answered = true;
            this.onScrollToBottom();
          });
      },
      setTabBar(code) {
        console.log('消失了输入框')
        this.setTabBarInput = code;
        this.showTabBar = code;
        this.changeScrollStatus(code)
      },
      changeScrollStatus(val) {
        this.scrollable = val;
        if(!val){
          this.messageScrollIntoView = 'scroll-top-id'
        }else{
          this.messageScrollIntoView = ''
          this.onScrollToBottom()
          this.showBottom = false
        }
        setTimeout(() => {
          this.messageScrollIntoView = ''
        },500)
      },
      changeInput(e) {
        this.recordStaus = false;
        this.editItinerary(e);
      },
      //获取AI目的地列表，得到列表后需要获取题词和获取会话ID
      async getAiDestList() {
         return new Promise(async (resolve, reject)=>{
          let res =  await this.$aiRequest({
            url: "/app/product/getDestList",
            method: "POST",
          })
          if (res.success) {
            this.aiDestList = res.data;
            uni.setStorageSync("aiDestList", JSON.stringify(res.data));
            // 获取本地目的地
            const item = uni.getStorageSync("aiDestItem");
            this.$refs.destBox.setDestList();
            // 如果存在并且在数据里面，就使用，因为有可能目的地被下架了或者其他情况不存在
            if (
              item &&
              res.data.filter((i) => i.destinationId === item.destinationId)[0]
            ) {
              // 不需要再次请求题词说话 因为后面有，init 也有， 所有加上code
              await this.destClick(item,'init');
            } else {
              await this.destClick(res.data[0], 'init');
            }
            console.log('请求目的地列表结束')
            resolve()
          }
         })
      },
      changeBox() {
        this.$refs.changeBox.close();
        uni.setStorageSync("changeDest", 0);
      },
      changeClick() {
        //切换为首页目的地
        this.destClick(this.destItem);
        this.$refs.changeBox.close();
        uni.removeStorageSync('articleList')
      },
      // 提问
      askQuestion(data) {
        if (data.type == 2) {
          //机器人说话  并且调用接口
          this.liveList = [data.articleId];
          this.getTemplateCard(8);
          return;
        }
        if (data.type == 1) {
          //机器人说话  默认文本
          this.robotSpeak(data.txt);
          return;
        }
        if (data.capsuleType == 8) {
          globalNextScene = 2
        }
        if (data.sceneCode) {
          globalNextScene = data.sceneCode
        }
        this.input = data.txt;
        this.sendAiMessage();
      },
      //对话回调公用方法
      callBackSetData({type,data}){
        if(type === 1){
          this.suggestActions = data
        }
        this.$forceUpdate()
      },
      suggestClick(item){
        console.log('suggestClick');
        // if (!this.$isLogin()) { // yuanbin 2024-05-16 16:18:28  登录校验先注释掉
        //   return;
        // }else{
          let txt = `${item.actionText}`;
          this.input = txt;
          this.suggestActionsItem = item
          userBehaviorDate.triggerType = 6
          this.recordStaus = false
          this.sendAiMessage();
          this.suggestActionsItem = ''
          this.showKeyWord = false
        // }
        
      },
      async handleInput(){
        if(this.input.length > 1){
          //请求服务端数据
          let params = {
            conversationId:this.conversationId,
            input:this.input
          }
          let res = await getPromptRetrieve(params)
          if(res.success && res.data){
            this.keyWordList = res.data
            //获取数据之后进行数据整理
            this.setKeyWordList(this.keyWordList)
          }
        }else{
          console.log(']]]]]]]]]]]]]1111')
          this.showKeyWord = false;
        }
      },
      setKeyWordList(keyWordList){
        var tipsList = keyWordList
        for(var i =0; i<tipsList.length; i++){
          tipsList[i].showTxt = tipsList[i].actionText.split(this.input)[1];
          tipsList[i].keyWord = this.input
        }
  
        this.showKeyList = tipsList
        if(tipsList.length > 0){
          this.showKeyWord = true;
        }else{
          console.log(']]]]]]]]]]]]]1111222222')
          this.showKeyWord = false;
        }
      },
      getHotelDetail(data){
        // this.detailPrams = data
        // this.$refs.details.getHotelDetail(data);
        // this.$refs.hotelInfoPopup.open()
        // console.log(data,'1111')
      },
      // hotelInfoPopupClose(){
      //   this.$refs.hotelInfoPopup.close()
      //   this.setTabBar(true)
      // },
      async initFun(){
        // this.onKeyboardHeightChange = this.onKeyboardHeightChange.bind(this);
        // uni.onKeyboardHeightChange(this.onKeyboardHeightChange);
        console.log('初始化了..............')
        // 获取ai目的地后请求题词机器人配置，会直接创建会话
        await this.getAiDestList();
        console.log('获取了AI目的地列表')
        let self = this;
        recorderManager.onStop(function (res) {
          self.voicePath = res.tempFilePath;
          self.voiceTime = res.duration;
          self.$refs.recordPopup.close();
          if (!self.isCancel) {
            self.sendServe();
          } else {
            self.isCancel = false;
          }
        });
        self.preloadImages();
        uni.$on("editItinerary", this.changeInput);
        uni.$on("changeScrollStatus", this.changeScrollStatus);
        // uni.$on("getHotelDetail",this.getHotelDetail)
        uni.$on("showModal2",this.showPopup)
        ///下单之后通知插入一条下单成功的消息
        uni.$on("payMess", this.payMess);
        //监听页面弹框
        uni.$on("showPopup", this.setTabBar);
        //监听日历插件弹框
        uni.$on("calendarBox", this.calendarBox);
        
        setTimeout(()=>{ //延时1秒在进行打招呼，防止数据加载慢
          // this.changeGifIndex( //首次进入，打招呼
          //   {
          //     code:0,
          //     type:true,
          //     timeOut:2300,
          //     index:3
          //   }
          // )
          // setTimeout(() => {
          this.changeGifIndex( // 打招呼后推荐，再站立
            {
              code:3,
              type:true,
              timeOut:2300,
              index:1
            }
          )
          // }, 2300);
        },1000)
      },
      //获取问题列表
      guidingSuggestActions(code){
        let destId = uni.getStorageSync('aiDestItem').destinationId;
        let params = {
          fresh: code ? true : false
        }
        if (!destId) {
          if (this.numberId <= 2) {
            setTimeout(() => {
              this.numberId++
              this.guidingSuggestActions();
            }, 300);
          }
        } else {
          this.$aiRequest({
            url:`/ai/aihub/chat/welcomeCard/changeNew`,
            params: {destId, version: '1.1'},
            method:'POST'
          }).then(res => {
            if(res.success){
              this.actionList = res.data
            }
          })
        }
      },
      changeQuestion(message) {
        const data = message.card.recProductQa
        let destId = uni.getStorageSync('aiDestItem').destinationId;
        this.$aiRequest({
          url:`/ai/aihub/chat/change`,
          params: {
            destId,
            questionList: data.questionList,
            query: data.query ? data.query : uni.getStorageSync('chatQuestion'),
            conversationId: this.conversationId,
            level: data.level,
            questionId: data.questionId,
          },
          method:'POST'
        }).then(res => {
          if(res.success){
            const messageIndex = this.messageData.datas.findIndex(e => e.chatId === message.chatId)
            this.messageData.datas[messageIndex].ai.card.recProductQa.hasChange = res.data.result.hasChange
            this.messageData.datas[messageIndex].ai.card.recProductQa.questionList = res.data.result.questionList
            this.$forceUpdate()
          }
        })
      },
      async onRefresh(){
        this.triggered = true
        // this.isShowAiGif = false;  // yuanbin 20250509 目前需求不需要隐藏数字人
        if(!this.showRecord){
          setTimeout(() => {
              this.triggered = false
          },500)
        }else{
          if(this.recordPageNo > this.allPageNo){
            setTimeout(() => {
                this.triggered = false
            },1000)
          }else{
            let params = {
              pageNo:this.recordPageNo,
              pageSize:10,
              params:{}
            }
            let res = await getChatRecordPage(params)
            
            if(res.success){
              this.recordPageNo++
              this.allPageNo = Math.ceil( res.data.total / 10)
              let reversedArray = res.data.records;
              this.recordPage = [...reversedArray,...this.recordPage];
              this.messageScrollIntoView = 'scroll-record' + '9'
              
            }
            this.triggered = false
          }
        }
      },
      onScroll(e){
        this.messageScrollIntoView = ''
        // console.log(e.detail);
        if (e.detail.scrollTop > this.lastScrollTop) {
          // 页面向下滚动
            // this.isShowAiGif = false;  // yuanbin 20250509 目前需求不需要隐藏数字人
        } else if (this.lastScrollTop - e.detail.scrollTop > 10) {
          // console.log('页面向上滚动了。。。。ck', e.detail);
          // 页面向上滚动
          this.showBottom = true
        }
        this.lastScrollTop = e.detail.scrollTop;
      },
      scrolltolower(){
        console.log('scrolltolower滚动到底部')
        
        this.showBottom = false
      },
      changeSendStatus(e){
        if(e != 0 && e != 1){
          this.sendStatus = false
        }else{
          this.sendStatus = true
        }
      },
      clearMessage(){
        this.$refs.clearPopup.open()
      },
      async sureClear(code){
        if(code == 1){
          // 清空记录(调用接口)
          let res = await clearRecord({})
          if(res.success){
            // 关闭ai返回结果显示
            this.showRecord = false
            await this.createChat();
            this.messageData.datas = []
            this.recordPage = []
            this.sendAiMessage(true);
            this.recordPageNo = 1
            this.allPageNo = 1
          }else{}
          
        }else{
          await this.createChat();
          if(this.messageData.datas.length< 1) return
          let len = this.messageData.datas.length -1
          this.messageData.datas[len].ai.showNewChat = true
          this.messageScrollIntoView = 'scroll-bottom-id'
        }
        uni.removeStorageSync('cardType')
        this.topProductArr = []
        topHomePageArr = []
        this.$refs.clearPopup.close()
      },
      toBottom(){
        // console.log('滚动到底部---');
        this.messageScrollIntoView = 'scroll-bottom-id'
        setTimeout(() => {
          this.showBottom = false
        },500)
      },
      calendarBox(){
        this.$refs.calendar.open();
      },
      calendarChange(e){
        // console.log(e)
        uni.$emit("setCalendarDate", e)
        this.$refs.calendar.close();
      },
      /**
       * 1, 判定是
       * 2，如果是，改变全局  dd = 1   0=用户主动输入 1-无操作 2-点击卡片返回 4-点击按钮 5-重新进入小程序 6=点击提词
       * */
      onshowCallback() {
        setTimeout(() => {
          uni.removeStorageSync("triggerType");
        }, 600);
      },
      async feedbackCall({type, chatId, flag}) {
    
        const feedbackStatus = flag
        let params = {
          chatId,
          feedbackStatus,
        };
        await this.$aiRequest({
          url: "/ai/aihub/chat/feedback",
          method: "POST",
          params,
        });
      },
      setTFn() {
        setTimeout(()=>{
        // 轮询请求获取算法的主动触发
           setInterval(()=>{
             // console.log('开始轮询.....')
             if (globalIsPollStatus) {
               // console.log('真实轮询..333333333333')
              this.pollSendAiMessage(true);
             }
           },1500)
        }, 2000)
      },
      sleep (ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
      },
      //控制打字机是否完成
      setPrintedStatus(data){
        this.printedStatus = data
      }
    },
    onShareAppMessage: function () {
      return { 
        title: "我发现一个有趣的AI旅行小管家，一起来看看吧~",
      };
    },
    onShareTimeline: function () {
      return { title: "我发现一个有趣的AI旅行小管家，一起来看看吧~" };
    },
    created() {
      this.onKeyboardHeightChange = this.onKeyboardHeightChange.bind(this);
  
      uni.getSystemInfo({
        success: (res) => {
          this.aiImgHeight = res.screenHeight * 0.657;
          this.aiImgWidth = this.aiImgHeight * 0.4486;
          this.aiImgLeft = 0.1735 * res.screenWidth;
        },
      });
    },
    async onLoad(options) {
      console.log('onLoad', options)
    },
    /**
     * 生命周期函数--监听页面隐藏
     */ onHide: function () {
       uni.offKeyboardHeightChange(this.onKeyboardHeightChange);
  
      globalIsPollStatus = false
      // 埋点
      this.postEventData("2003", "页面离开", "0.0");
      uni.removeStorageSync("askQuestion");
      uni.removeStorageSync("triggerType");
      // this.optionsData.shareTokenId = ""
    },
    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function () {
      uni.offKeyboardHeightChange(this.onKeyboardHeightChange);
      // 埋点
      this.postEventData("2003", "页面离开", "0.0");
      this.inMessageTips = [];
      ///取消监听
      uni.$off("payMess", this.payMess);
      uni.removeStorageSync("askQuestion");
      uni.removeStorageSync("triggerType");
      // 跳出页面时清除商品卡片信息
      uni.removeStorageSync("cardType");
      this.signOutService();
      // 跳出页面时清除shareTokenId
      // this.optionsData.shareTokenId = ""
    },
    async onShow() {
      uni.offKeyboardHeightChange(this.onKeyboardHeightChange); // 安全取消
      uni.onKeyboardHeightChange(this.onKeyboardHeightChange);
      let routes = getCurrentPages()
      const previousPage = routes[routes.length - 1];
      const enterOptions = uni.getEnterOptionsSync();
      let showOptions = previousPage.options
      
      console.log(this.isFirstInit, '===========================第一次进入')
      // 第一次进入页面时需要初始化数据
      if(this.isFirstInit) {
        // yuanbin 20250503 暂时给showOptions赋值， 因为没有参数， 不清楚是从哪获取的
        if(!showOptions){
          showOptions = {
            login: false,
            scene: 'allInOne=123456789'
          }
        }
        if(!showOptions.scene){
            showOptions.scene = 'allInOne=123456789'
        }
        console.log('showOptions',showOptions)
        // 获取参数
        if (showOptions&& showOptions.scene) {
          let strObj = decodeURIComponent(showOptions.scene)
          let shareKey =  strObj.split('=')[0]
          let shareIdValue =  strObj.split('=')[1]
          // 得到数字化大屏数据
          if(shareKey == 'allInOne') {
            this.shareText = shareIdValue
            let shareMessage = await getUserMessage({
              id: shareIdValue
            })
            console.log(shareMessage, '=============-00000000008888888888', shareMessage.data.message)
  
            uni.setStorageSync('shareMessageText',shareMessage.data.message)
            let destJson = {destinationId: shareMessage.data.destId,
              destinationName: shareMessage.data.destinationName
            }
            this.aiDestItem = destJson
            uni.setStorageSync('aiDestItem',destJson)
  
            // if (!this.$isLogin()) { // yuanbin 2024-05-16 16:18:28  登录校验先注释掉
            //   return;
            // }
            // 有消息的时候才调用接口去获取返回值
            if(shareMessage.data.message){
              setTimeout(() => {
                if (this.isPolling) {
                  this.onButtonClick() 
                }
                console.log('提问=================')
                this.askQuestion({
                  txt: shareMessage.data.message,
                });
                uni.setStorageSync('shareMessageText','')
              }, 500);
            }
          } else {
            this.optionsData = {
              shareTokenId: shareIdValue
            }
          }
  
        } else {
          this.optionsData = showOptions
        }
        // 需要登录的时候，未登录直接跳转登录
        if(showOptions.login && !uni.getStorageSync('Authentication')){
          // yuanbin 20250503 暂时不跳转登录页面
          return
          setTimeout(()=>{this.isFirstInit = false}, 1000)
          // 未登录，登录回来进行轮询，或者不登录
          setTimeout(()=>{
            this.setTFn()
          },5000)
          this.$navTo('/commonSubPack/pages/login/index',{},'navigateTo')
          return
        }else{
          setTimeout(()=>{this.isFirstInit = false}, 1000)
          console.log('onLoad加载中初始化', showOptions)
          await this.initFun()
        }
  
        let params = {
          pageNo:1,
          pageSize:10,
          params:{}
        }
        // 登录展示聊天记录
        if(uni.getStorageSync('Authentication')){
          getChatRecordPage(params).then(res => {
            console.log('res', res)
            if(res.data.total > 0){
              this.showRecord = true
            }else{
              this.showRecord = false
            }
          })
        }
        this.isFirstInit = false
        this.setTFn()
      } else {
        //不是第一次进入页面，并且没有请求过订单
        if(uni.getStorageSync('Authentication')){
          this.guidingSuggestActions(1)
        }
        let destItem = uni.getStorageSync("destItem")
        this.getAiIconFun(destItem.destinationId)
        // 动态更新出行人属性
        this.travelerWith = !this.travelerWith
        let shareMessageText =  uni.getStorageSync('shareMessageText')
        // 登录完成后返回
        if( uni.getStorageSync('shareMessageText')){
           setTimeout(() => {
              if (this.isPolling) {
                this.onButtonClick() 
              }
              console.log('提问=================')
              this.askQuestion({txt: shareMessageText});
              uni.setStorageSync('shareMessageText','')
          }, 500);
        }
   
      }
      if(uni.getStorageSync('changeDest')){
        this.suggestActions = []
        uni.setStorageSync('changeDest',false)
      }
      if (uni.getStorageSync("triggerType")) {
        globalTriggerType = uni.getStorageSync("triggerType")
      }
      globalIsPollStatus = true
      if (uni.getStorageSync("isFromDspDetail")) {
        this.getDspProduct();
      }
      if(routes.length > 1) {// 判断是否热启动，热启动不会进入onload，只会进入onshow
        showOptions = decodeURIComponent(enterOptions.query)
        if(showOptions && showOptions.scene) {
          console.log('showOPtions:', showOptions)
          let strObj = decodeURIComponent(showOptions.scene)
          let shareIdValue =  strObj.split('=')[1]
          this.optionsData = {
            shareTokenId: shareIdValue
          }
        } else {
          this.optionsData = showOptions
        }
      }
      // 从订单详情-出行助手-出行必备过来，唤出AI写真卡片
      if (uni.getStorageSync('shareTokenId')) {
        this.optionsData = {
          shareTokenId: uni.getStorageSync('shareTokenId')
        }
      }
      //如果当前目的地不等于缓存目的地，并且缓存有ai目的地列表
      if(
        uni.getStorageSync("aiDestItem").destinationId != this.aiDestItem.destinationId && 
        uni.getStorageSync("aiDestList")
      ){
        let item = uni.getStorageSync("destItem")
        this.navIndex = 0;
        uni.setStorageSync("changeDest", 0);
        uni.setStorageSync("aiDestItem", item);
        uni.setStorageSync("destItem", item);
        this.aiDestItem = item;
      }
      this.getMapPreview(uni.getStorageSync("destItem").destinationId);
      this.recordStaus = false;
      if (!this.conversationId) {
        console.log('曝光，但是没有会话ID..............')
  
      }
      // 如果从商品/订单过来，将记录清除
      if (uni.getStorageSync('aiObj')) {
        this.messageData.datas = []
      }
      // 获取出行提醒
      this.upcomingTravel();
      this.enterTime = new Date();
      //	#ifdef H5
      let getAppSpmParam = JSON.parse(dsbridges.getAppSpmParam());
      if (getCurrentPages().length == 1) {
        this.parentSpm = {
          ref: getAppSpmParam.events[0].spm_cnt, //上级页面点击位置
          pre: getAppSpmParam.events[0].spm_ref, //上上级点击位置
        };
      }
      if (this.$store.$state && this.$store.$state.parentSpm) {
        this.parentSpm = this.$store.$state.parentSpm; // 获取页面来源页信息
      }
      if (this.$store.state && this.$store.state.parentSpm) {
        this.parentSpm = this.$store.state.parentSpm; // 获取页面来源页信息
      }
      // let spmData = this.getEventObj("2003", "页面离开", "0.0");
      this.$store.commit("SET_POINT_DATA", pointData);
      this.$store.commit("SET_SPM_DATA", spmData);
      //	#endif
      // 延时，等onload  optionsData有值接收再上报
      setTimeout(()=>{
        this.postEventData("2002", "页面进入", "0.0", this.optionsData);
      },100)
  
      if (uni.getStorageSync("askQuestion")) {
        console.log('uni.getStorageSync("askQuestion")', uni.getStorageSync("askQuestion"));
        setTimeout(() => {
          if (this.isPolling) {
            this.onButtonClick() 
          }
          console.log('提问=================')
          this.askQuestion(uni.getStorageSync("askQuestion"));
        }, 500);
        setTimeout(() => {
          uni.removeStorageSync("askQuestion");
        }, 600);
      }
      this.onshowCallback()
  
    },
    beforeCreate(){}
  };
  </script>
  
  <style lang="scss" scoped>
  $baseUrl: "https://cdn1.visiotrip.com/h5AndMini/2023-";
  
	html,
	body {
		height: 100vh;
    overflow: hidden;
	}
  .scroll-top {
    height: 52rpx;
    width: 522rpx;
    position: absolute;
    z-index: 1;
    bottom: -52rpx;
    right: 28rpx;
  }
  .scroll-bottom {
    height: 52rpx;
    width: 512rpx;
    position: absolute;
    z-index: 1;
    top: -38rpx;
    right: 28rpx;
  }
  .to-bottom{
    position: absolute;
    width: 128rpx;
    height: 128rpx;
    right: 0;
    top: -110rpx;
    z-index: 10;
  }
  .service-box {
    width: 100%;
    height: 140rpx;
    position: sticky;
    z-index: 9;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: #ffffff;
    border-radius: 26rpx;
    border: 4rpx solid #B4EF4E;
    padding: 12rpx;
    margin-top: 16rpx;
    .service-left-box {
      display: flex;
      align-items: center;
      .service-img {
        width: 116rpx;
        height: 116rpx;
        border-radius: 16rpx;
      }
      .service-content-box {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        margin: 12rpx 49rpx 12rpx 20rpx;
        flex: 1;
        .service-title {
          font-weight: 600;
          font-size: 28rpx;
          color: #404062;
          line-height: 40rpx;
          margin-bottom: 18rpx;
        }
        .service-price {
          display: flex;
          align-items: center;
          .price {
            font-weight: 600;
            font-size: 24rpx;
            color: #F93F55;
            line-height: 34rpx;
          }
          .code {
            font-weight: 400;
            font-size: 20rpx;
            color: #B5B5D2;
            line-height: 20rpx;
          }
        }
      }
    }
    .service-right {
      width: 180rpx;
      height: 66rpx;
      font-weight: 600;
      font-size: 28rpx;
      color: #131328;
      line-height: 66rpx;
      text-align: center;
      background: #B4EF4E;
      border-radius: 16rpx;
      margin-right: 25rpx;
    }
  }
  .view-page {
    position: relative;
    width: 100%;
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: none;// background-color: white;
  
    .nav-bar {
      flex-shrink: 0;
      position: relative;
      display: flex;
      align-items: flex-end;
      justify-content: center;
      .title {
        width: 190rpx;
        height: 76rpx;
        z-index: 5;
      }
  
      .nav-bg-img {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
      }
      .nav-left-view {
        display: flex;
        align-items: center;
        position: absolute;
        left: 28rpx;
        bottom: 10rpx;
        .back-img {
          width: 60rpx;
          height: 60rpx;
          margin-right: 12rpx;
        }
      }
  
      .nav-left-box {
        display: flex;
        color: $sl-color-grey;
        z-index: 5;
        width: 148rpx;
        height: 60rpx;
        background: rgba(253, 255, 235, 0.80);
        border-radius: 29rpx;
        backdrop-filter: blur(6px);
        align-items: center;
        justify-content: center;
        .left-icon {
          width: 108rpx;
          height: 108rpx;
        }
        .dest-name {
          font-size: 24rpx;
          color: $sl-color-black;
          padding-right: 7rpx;
          font-weight: 600;
        }
      }
    }
  
    .page-bg {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      z-index: -2;
    }
  
    .ai-chat {
      position: absolute;
      left: 283rpx;
      top: 0;
      z-index: 0;
    }
  
    .page-view {
      width: 100%;
      flex-grow: 1;
      position: relative;
      overflow: hidden;
      display: flex;
      height: 100%;
      flex-direction: column;
      background-color: #E0F5EB;
      &.bg {
        margin-top: 228rpx;
        // background: url('https://cdn1.visiotrip.com/h5AndMini/2024-09-19/chat-bg.png');
        border-radius: 48rpx 48rpx 0rpx 0rpx;
        background-size: cover;
      }
  
      .scroll-view {
        box-sizing: border-box;
        flex-grow: 1;
        width: 100%;
        overflow: hidden;
        position: relative;
        padding-top: 20rpx;
        &.hasMargin {
          margin-top: 140rpx;
        }
        .scroll-content {
          display: flex;
          flex-direction: column;
          align-items: stretch;
          padding: 0rpx 28rpx 70rpx 28rpx;
          position: relative;
        }
        .pic-status-box {
          display: flex;
          justify-content: flex-end;
          margin-top: 16rpx;
        }
        .pic-status-view {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 420rpx;
          height: 420rpx;
          background: #E4E4F4;
          border-radius: 26rpx;
          .poi-status-img {
            width: 82rpx;
            height: 82rpx;
          }
        }
      }
  
      .input-box {
        flex-shrink: 0;
        display: flex;
        flex-direction: column;
        z-index: 1;
        position: relative;
        -webkit-backface-visibility: hidden; /* 避免元素闪烁 */
        -webkit-transform: translateZ(0); /* 强制 GPU 渲染 */
        opacity: 1;
        &.ios-hid {
          opacity: 0;
        }
        .textarea-box {
          position: relative;
          // width: 100%;
          padding: 21rpx 32rpx;
          margin: 0 28rpx;
          display: flex;
          flex-direction: row;
          // border-bottom: 1px solid #e7e7e7;
          align-items: center;
          background: #ffffff;
          box-shadow: 0rpx 8rpx 14rpx 0rpx rgba(64,64,98,0.14);
          border-radius: 36rpx;
          margin-top: 20rpx;
          &.border-none {
            border-bottom: none;
          }
          .tab-voice {
            z-index: 5;
            width: 48rpx;
            height: 48rpx;
            background: url("https://cdn1.visiotrip.com/h5AndMini/2024-09-19/input-type-1.png") 0 0 no-repeat;
            background-size: 100%;
            margin-right: 24rpx;
            &.record {
              background: url("https://cdn1.visiotrip.com/h5AndMini/2024-09-19/input-type-2.png") 0 0 no-repeat;
              background-size: 100%;
            }
          }
  
          .input-text-warp {
            width: 564rpx;
            min-height: 64rpx !important;
            height: 100% !important;
            box-sizing: border-box;
            padding: 3rpx;
            position: relative;
            // background: url($baseUrl + "09-14/input-bg-top.png") left top
            //     no-repeat,
            //   url($baseUrl + "09-14/input-bg-bot.png") left bottom no-repeat;
            // background-size: 100% auto;
            background-color: rgba(255, 255, 255, 0.86);
            border-radius: 42rpx;
            display: flex;
            align-items: center;
            .input-text-cont-bg {
              position: absolute;
              left: 0;
              top: 37rpx;
              bottom: 39rpx;
              z-index: 1;
              width: 100%;
              background: url($baseUrl + "09-14/input-bg-con.png") left top
                repeat-y;
              background-size: 100% auto;
            }
            &.text-warp-record {
              // border-radius: 14rpx;
              // background: linear-gradient(90deg, #3CB7FE 0%, #BF35FF 100%);
            }
  
            .input-textarea {
              z-index: 3;
              padding: 9rpx 0 9rpx 4rpx;
              flex-grow: 1;
              font-size: 32rpx;
              color: $sl-color-black;
              line-height: 46rpx;
              width: 370rpx;
              min-height: 46rpx !important;
              max-height: 150rpx !important;
              border-radius: 42rpx;
            }
            // @keyframes rotate {
            //   from {
            //     transform: rotate(0deg);
            //   }
            //   to {
            //     transform: rotate(360deg);
            //   }
            // }
            .send-load-icon {
              width: 40rpx;
              height: 40rpx;
              background: url($baseUrl + "09-14/ai-loading.png") 0 0 no-repeat;
              background-size: 100%;
              position: absolute;
              right: 44rpx;
              top: 22rpx;
              z-index: 99;
              animation: spin 2s linear infinite;
            }
  
            .press-on-speak {
              height: 32rpx;
              font-size: 32rpx;
              font-weight: 600;
              text-align: center;
              color: $sl-color-black;
              line-height: 32rpx;
              width: 80%;
              z-index: 5;
              display: flex;
              align-items: center;
              justify-content: center;
              .press-on-speak-icon {
                width: 123rpx;
                height: 30rpx;
              }
            }
          }
  
          .textarea-placeholder {
            font-size: 28rpx;
            font-weight: 400;
            color: #4d566a;
            line-height: 40rpx;
          }
  
          .send-btn {
            flex-shrink: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            margin-left: 14rpx;
            width: 64rpx;
            height: 64rpx;
            border-radius: 20rpx;
            font-size: 28rpx;
            font-family: PingFangSC-Medium, PingFang SC;
            font-weight: 500;
            color: #ffffff;
            line-height: 50rpx;
            background: url("") 0 0 no-repeat;
            background-size: 100%;
            position: absolute;
            right: 32rpx;
            bottom: 21rpx;
            &.disabled {
              background: url("https://cdn1.visiotrip.com/h5AndMini/2024-09-19/msg-send-disable.png") 0 0 no-repeat;
              background-size: 100%;
            }
  
            &.send-status {
              width: 48rpx;
              height: 48rpx;
              margin-left: 14rpx;
              background: url("") 0 0 no-repeat;
              background-size: 100%;
              bottom: unset;
            }
          }
          .talk_box{
            position: absolute;
            left: 0;
            top: 0;
            z-index: 100;
            width: 100%;
            height: 106rpx;
            background: #131328;
            border-radius: 36rpx;
            box-shadow: 0rpx 8rpx 14rpx 0rpx rgba(64,64,98,0.14);
            .talk_text{
              position: absolute;
              top: -58rpx;
              left: 50%;
              transform: translateX(-50%);
              font-weight: 600;
              font-size: 24rpx;
              color: #767697;
              line-height: 24rpx;
            }
          }
        }
  
        .max-space {
          text-align: center;
          margin: 0 auto;
          // height: calc(90rpx + constant(safe-area-inset-bottom));
          // height: calc(90rpx + env(safe-area-inset-bottom));
          height: 90rpx;
          font-weight: 500;
          font-size: 20rpx;
          color: rgba(181,181,210,0.6);
          line-height: 20rpx;
          padding-top: 28rpx;
  
          &.focus-state {
            height: calc(238rpx + constant(safe-area-inset-bottom));
            height: calc(238rpx + env(safe-area-inset-bottom));
          }
        }
  
        .min-space {
          height: max(20rpx, constant(safe-area-inset-bottom));
          height: max(20rpx, env(safe-area-inset-bottom));
        }
      }
    }
  }
  
  .popup-content {
    width: 326rpx;
    height: 170rpx;
    padding-top: 35rpx;
    background: url($baseUrl + "06-22/play-bg@2x.png") 0 0 no-repeat;
    background-size: 100%;
  
    .content-record-icon {
      width: 255rpx;
      height: 93rpx;
      margin: 0 auto;
      background: url($baseUrl + "06-22/record-play.png") 0 0 no-repeat;
      background-size: 100%;
    }
  }
  
  .record-bo-box {
    position: fixed;
    z-index: 99999999999;
    bottom: 0;
    left: 0;
    width: 750rpx;
    height: 365rpx;
    background: url($baseUrl + "06-22/record-b.png") 0 0 no-repeat;
    background-size: 100%;
  
    .record-text {
      width: 100%;
      margin-top: -56rpx;
      text-align: center;
      height: 36rpx;
      font-size: 28rpx;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #9ea0a1;
      line-height: 36rpx;
  
      &.record-text-can {
        margin-top: -161rpx;
        text-align: right;
        padding-right: 46rpx;
      }
    }
  
    .record-can {
      width: 103rpx;
      height: 103rpx;
      background: #606060;
      text-align: center;
      font-size: 28rpx;
      border-radius: 55rpx;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #9b9d9f;
      line-height: 103rpx;
      margin: -141rpx 0 0 601rpx;
      background: url($baseUrl + "06-22/close.png") 0 0 no-repeat;
      background-size: 100%;
  
      &.can-btn {
        background: url($baseUrl + "06-22/close-1.png") 0 0 no-repeat;
        background-size: 100%;
      }
    }
  
    .record-icon {
      position: absolute;
      top: 102rpx;
      left: 356rpx;
      width: 38rpx;
      height: 54rpx;
      background: url($baseUrl + "06-22/record.png") 0 0 no-repeat;
      background-size: 100%;
    }
  }
  
  
  :deep(.uni-swiper__dots-item){
    margin: 0 13rpx;
  }
  
  :deep(.uni-swiper__dots-item:first-child) {
    margin: 0 13rpx !important;
  }
  
  :deep(.uni-popup .uni-popup__wrapper) {
    background: transparent !important;
  }
  
  // 行程弹框详情开始
  .detail-box {
    padding: 0 34rpx 0 70rpx;
  }
  
  .info-box {
    width: 690rpx;
    height: 107rpx;
    border-radius: 30rpx;
    border: 1rpx solid #979797;
    margin: 30rpx auto;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
  
    .line {
      width: 1rpx;
      height: 57rpx;
      // border: 1rpx solid #BEBEBE;
      background: #bebebe;
    }
  
    // .info-txt {
    //   flex: 1;
    //   text-align: center;
  
    //   view {
    //     color: #999999;
    //     font-size: 24rpx;
    //   }
  
    //   view.active {
    //     font-size: 28rpx;
    //     color: $sl-color-grey;
    //     font-weight: 600;
    //   }
    // }
  }
  
  .day-list {
    white-space: nowrap;
    width: 100%;
    height: 130rpx;
  
    .day-txt {
      display: inline-block;
      line-height: 130rpx;
      color: #848891;
      font-size: 28rpx;
      width: 150rpx;
      text-align: center;
    }
  
    .day-txt.active {
      font-size: 36rpx;
      color: $sl-color-grey;
      font-weight: 600;
    }
  }
  
  .view-box-1 {
    position: relative;
  
    .day-title {
      font-size: 32rpx;
      color: $sl-color-grey;
      font-weight: 600;
      padding-bottom: 20rpx;
    }
  
    .day-content {
      font-size: 28rpx;
      color: #848891;
      padding-bottom: 16rpx;
    }
  }
  
  .view-box-2 {
    padding: 0 30rpx 40rpx 30rpx;
  
    .box-2-title {
      font-size: 28rpx;
      color: $sl-color-grey;
      font-weight: 600;
      padding-bottom: 20rpx;
    }
  
    .box-2-content {
      background: #f4f8ff;
      width: 100%;
      padding: 13rpx 30rpx;
  
      .content-list {
        font-size: 28rpx;
        color: $sl-color-grey;
        margin: 5rpx 0;
      }
    }
  }
  
  .radius-top::before {
    content: "";
    width: 14rpx;
    height: 14rpx;
    background: #ff4a01;
    position: absolute;
    left: -35rpx;
    top: 11rpx;
    z-index: 2;
    border-radius: 50%;
  }
  
  .line-box::after {
    content: "";
    width: 1rpx;
    height: 100%;
    position: absolute;
    left: -29rpx;
    top: 11rpx;
    border-left: 2rpx dashed #d8d8d8;
    z-index: 1;
  }
  
  // 行程弹框详情结束
  
  @keyframes spin {
    from {
      transform: rotate(0deg);
    }
  
    to {
      transform: rotate(360deg);
    }
  }
  
  // 卡片
  
  .image {
    // height: 640rpx;
    // width: 480rpx;
    border-radius: 24rpx;
  }
  
  .card-content-box {
    width: 750rpx;
    height: 1444rpx;
    background: #f3f3f3;
    padding: 30rpx;
    // border-radius: 30rpx 30rpx 0rpx 0rpx;
    border-radius: 30rpx 30rpx 30rpx 30rpx;
    opacity: 1;
  }
  
  .raider-location {
    display: flex;
    padding: 0 20rpx;
  
    .van-icon-location-wrap {
      // width: 120rpx;
      display: flex;
      height: 38rpx;
      background: #e0e8ff;
      border-radius: 4rpx 4rpx 4rpx 4rpx;
      opacity: 1;
      margin-right: 10rpx;
      position: relative;
      .van-icon-loca-box {
        width: 30rpx;
        height: 30rpx;
        background: #687af0;
        border-radius: 4rpx 4rpx 4rpx 4rpx;
        position: absolute;
        top: 4rpx;
        left: 4rpx;
        .van-icon-location {
          width: 24rpx;
          height: 24rpx;
          position: absolute;
          top: 4rpx;
          left: 4rpx;
          padding: 0;
        }
      }
      .text {
        font-size: 22rpx;
        font-family: PingFang SC-Regular, PingFang SC;
        font-weight: 400;
        color: #547ae4;
        line-height: 38rpx;
        margin: 0 10rpx 0 40rpx;
      }
    }
  }
  :deep(.card-box-content) {
    background: #fff;
  }
  
  .des_text_panel {
    margin-top: 28rpx;
    text-align: center;
    font-size: 36rpx;
    font-weight: bold;
    color: #fff;
  }
  
  .close-icon {
    position: absolute;
    left: 30rpx;
    top: 30rpx;
    width: 44rpx;
    height: 44rpx;
    z-index: 3;
  }
  
  .raider-source-text {
    position: absolute;
    right: 13rpx;
    top: 36rpx;
    padding: 0 15rpx;
    height: 44rpx;
    // background: rgba(0, 0, 0, .42);
    // border-radius: 22rpx 22rpx 22rpx 22rpx;
    // opacity: 0.42;
    font-size: 24rpx;
    font-family: PingFangSC-Regular-, PingFangSC-Regular;
    font-weight: normal;
    color: #ffffff;
    line-height: 44rpx;
  
    .source-icon {
      display: inline-block;
    }
  }
  
  .card-box {
    position: fixed;
    z-index: 999999999;
    bottom: 0;
  }
  .cards-item {
    height: 1106rpx;
    border-radius: 30rpx;
    box-shadow: 0rpx 1rpx 8rpx 1rpx rgba(0, 0, 0, 0.04);
  
    background-color: #fff;
  
    .card-img {
      width: 690rpx;
      height: 650rpx;
      background: #ffffff;
      box-shadow: 0rpx 1rpx 8rpx 1rpx rgba(0, 0, 0, 0.04);
      border-radius: 30rpx 30rpx 0 0;
      opacity: 1;
    }
  
    .raiders-title {
      font-size: 32rpx;
      font-weight: bold;
      height: 45rpx;
      font-family: PingFang SC-Bold, PingFang SC;
      color: #4d566a;
      line-height: 45rpx;
      margin: 20rpx 20rpx 10rpx 20rpx;
      @include maxLine(2);
    }
  
    .raiders-txt-box {
      margin: 20rpx 20rpx 10rpx 20rpx;
      line-height: 38rpx;
      padding: 20rpx;
      background: #f4f8ff;
      border-radius: 10rpx 10rpx 10rpx 10rpx;
      font-size: 26rpx;
      color: #4d566a;
    }
    .raiders-txt {
      line-height: 38rpx;
      font-size: 26rpx;
      color: #4d566a;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  
    .ai-txt {
      margin: 20rpx 20rpx 30rpx 20rpx;
      font-size: 28rpx;
      color: #4d566a;
      line-height: 40rpx;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 4;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  
    .ai-txt-title {
      font-weight: bold;
      display: inline-block;
      background: url($baseUrl + "07-11/icon3@2x.png") 0 0 no-repeat;
      background-size: 100%;
    }
  }
  
  .imageBottom {
    width: 650rpx;
    height: 18rpx;
    // background: rgba(204, 204, 204, 0.2);
    background: rgba(255, 255, 255, 0.6);
    border-radius: 0 0 30rpx 30rpx;
    opacity: 1;
    position: relative;
    margin: 0 auto;
  }
  
  .imageBottom2 {
    width: 610rpx;
    height: 18rpx;
    // background: RGBA(177, 177, 177, 0.4);
    background: rgba(255, 255, 255, 0.3);
    border-radius: 0 0 30rpx 30rpx;
    position: relative;
    margin: 0 auto;
  }
  
  .operation_panel {
    width: 100%;
    // margin-top: 36rpx;
    display: flex;
    justify-content: space-between;
    z-index: 99;
    padding: 0 50rpx 0 60rpx;
  }
  
  .operation_item {
    display: flex;
    flex-direction: column;
    align-items: center;
    position: relative;
  }
  
  .operation_name {
    margin-top: 15rpx;
    font-size: 24rpx;
    font-weight: bold;
    color: #4d566a;
    line-height: 38rpx;
    font-family: PingFang SC-Bold, PingFang SC;
  }
  
  .operation_name1 {
    margin-top: 25rpx;
  }
  .like {
    .icon_panel {
      height: 100rpx;
      width: 100rpx;
    }
  }
  
  .icon_panel {
    height: 80rpx;
    width: 80rpx;
    // background-color: #eb8383;
    border-radius: 50%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
  }
  
  .icon_panel-0 {
    margin-top: 11rpx;
  }
  
  .icon_card_img {
    width: 552rpx;
    height: 87rpx;
    opacity: 1;
    position: absolute;
    top: -93rpx;
    right: -36rpx;
  }
  
  .icon_img1 {
    width: 80rpx;
    height: 80rpx;
  }
  .icon_img {
    width: 100rpx;
    height: 100rpx;
  }
  .maskDest {
    position: fixed;
    width: 680rpx;
    /* min-height: 230rpx; */
    background: #fff;
    left: 50%;
    margin-left: -340rpx;
    border-radius: 48rpx;
    box-shadow: 0rpx 8rpx 16rpx 0rpx rgba(130, 149, 212, 0.32);
  }
  .changeBox {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 17rpx 17rpx 15rpx 32rpx;
    position: relative;
    .icon-2 {
      width: 25rpx;
      height: 15rpx;
      position: absolute;
      top: -14rpx;
      left: 40rpx;
    }
    .changeBtn {
      padding: 0 20rpx;
      height: 60rpx;
      background: $sl-color-light-blue;
      border-radius: 30rpx;
      line-height: 60rpx;
      color: #ffffff;
      font-size: 28rpx;
    }
    .changeTxt {
      color: $sl-color-dark-grey;
      font-size: 32rpx;
    }
  }
  .printe-text {
    width: 710rpx;
    margin: 0 auto;
    color: $sl-color-dark-grey;
    font-size: 28rpx;
    padding: 0 20rpx 40rpx 20rpx;
  }
  .str-bottom {
    width: 670rpx;
    height: 120rpx;
    background: rgba(255, 255, 255, 0.86);
    box-shadow: 0rpx 6rpx 24rpx 0rpx rgba(0, 0, 0, 0.12),
      0rpx 10rpx 30rpx 0rpx rgba(0, 0, 0, 0.08);
    border-radius: 100rpx;
    backdrop-filter: blur(6px);
    position: fixed;
    bottom: 70rpx;
    left: 50%;
    margin-left: -335rpx;
    display: flex;
    justify-content: space-evenly;
    .bottom-box.active {
      transform: scale(0.8);
      transition: transform 0.5s;
    }
    .bottom-box {
      display: flex;
      align-items: center;
      color: $sl-color-black;
      font-size: 24rpx;
      position: relative;
      transform: scale(1);
      transition: transform 0.5s;
      .icon-1 {
        width: 62rpx;
        height: 57rpx;
        margin-right: 12rpx;
      }
      .icon-2 {
        width: 56rpx;
        height: 56rpx;
        margin-right: 12rpx;
      }
      .icon-3 {
        width: 62rpx;
        height: 60rpx;
        margin-right: 12rpx;
      }
    }
  }
  .collect {
    width: 309rpx;
    height: 47rpx;
    background: #f8b840;
    box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(180, 126, 25, 0.2);
    border-radius: 2rpx 20rpx 2rpx 20rpx;
    justify-content: center;
    display: flex;
    align-items: center;
    color: #ffffff;
    position: absolute;
    top: -32rpx;
    left: -145rpx;
    .collect-2 {
      width: 19rpx;
      height: 19rpx;
    }
  }
  .collect-1 {
    width: 19rpx;
    height: 11rpx;
    position: absolute;
    top: 14rpx;
    right: 25rpx;
  }
  .press-on-speak-icon-1 {
    // width: 184rpx;
    height: 46rpx;
    position: absolute;
    left: 72rpx;
    top: 50%;
    margin-top: -23rpx;
    z-index: 2;
    font-weight: 600;
    font-size: 32rpx;
    color: #B5B5D2;
    line-height: 46rpx;
  }
  .chat-zn{
    width: 174rpx;
    height: 66rpx;
    margin-left: 47rpx;
    margin-right: 10rpx;
    &.dsn {
      width: 288rpx;
    }
  }
  .scroll-view-x{
    white-space: nowrap;
      width: 70%;
    margin: 0 auto;
    .scroll-view-item_H {
          display: inline-block;
      min-width: 96rpx;
      height: 66rpx;
      background: #F2F6FF;
      border-radius: 34rpx;
      text-align: center;
      line-height: 66rpx;
      padding: 0 32rpx;
      margin: 0 18rpx 0 0;
      color: $sl-color-grey;
      font-size: 24rpx;
      }
  }
  .keyWordBox{
    position: fixed;
    z-index: 3;
    width: 100%;
  }
  .keyList{
    width: auto;
    max-height: 604rpx;
    background: #FFFFFF;
    border-radius: 26rpx;
    backdrop-filter: blur(10.8695652173913px);
    transition: height 1s ease;
    margin: 0 28rpx;
    padding: 40rpx 40rpx 0 40rpx;
    .key-flex{
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 68rpx;
      padding-bottom: 40rpx;
      .key-txt{
        
        font-size: 28rpx;
        flex: 1;
        .key-txt-1{
          color: $sl-color-dark-grey;
          font-weight: bold;
        }
        .key-txt-2{
          color: $sl-color-grey;
        }
      }
      .key-icon{
        width: 24rpx;
        height: 24rpx;
      }
    }
  }
  .key-mask{
    position: fixed;
    width: 100%;
    height: 100%;
    background: rgba(236, 240, 255,.3);
    top: 0;
    left: 0;
    z-index: 2;
  }
  .hotelInfo-scroll{
    border-radius: 48rpx 48rpx 0 0;
    overflow: hidden;
  }
  .record-txt{
    width: 100%;
    height: 34rpx;
    line-height: 34rpx;
    margin-top: 36rpx;
    text-align: center;
    color:#B5B5D2;
    font-size: 24rpx;
    position: relative;
    .border-box-left{
      width: 206rpx;
      height: 1rpx;
      background: #C0C0DA;
      position: absolute;
      top: 18rpx;
      z-index: 1;
      left: 0;
    }
    .border-box-right{
      width: 206rpx;
      height: 1rpx;
      background: #C0C0DA;
      position: absolute;
      top: 18rpx;
      z-index: 1;
      right: 0;
    }
    .txt-box{
      width: 280rpx;
      height: 40rpx;
      margin: 0 auto;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
  .clear-box{
    width: 600rpx;
    height: 364rpx;
    background: #FFFFFF;
    border-radius: 26rpx;
    .clear-title{
      color:#131328;
      font-size:36rpx;
      height: 170rpx;
      text-align: center;
      border-bottom:1rpx solid #E4E4F4;
      display: flex;
      align-items: center;
      padding: 0 43rpx;
    }
    .clear-txt-1{
      height: 88rpx;
      text-align: center;
      line-height: 88rpx;
      border-bottom:1rpx solid #E4E4F4;
      color:#5876D6;
      font-size:32rpx;
    }
    .clear-txt-2{
      height: 88rpx;
      text-align: center;
      line-height: 88rpx;
      color:#131328;
      font-size:32rpx;
    }
  }
  .clear-icon{
    width: 60rpx;
    height: 60rpx;
    bottom: 10rpx;
    position: absolute;
  }
  .calendarBox {
      height: 75vh;
      border-radius: 30rpx 30rpx 0 0;
      background: #ffffff;
    }
  .phone-box {
    width: 202rpx;
    height: 66rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.8);
    border-radius: 34rpx;
    border: 4rpx solid #FFFFFF;
    margin-left: 12rpx;
    .phone-img {
      width: 38rpx;
      height: 38rpx;
      margin-right: 8rpx;
    }
    text {
      height: 40rpx;
      font-weight: 600;
      font-size: 28rpx;
      color: #404062;
      line-height: 40rpx;
    }
  }
  .changeOkBox {
    width: 358rpx;
    height: 48rpx;
    background: rgba(255,255,255,0.5);
    border-radius: 24rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 24rpx auto 0 auto;
    &.active{
      width: 190rpx;
    }
    .lineBox {
      width: 130rpx;
      height: 2rpx;
      background: #eeeeee;
    }
    .lineTxt {
      text-align: center;
      height: 24rpx;
      font-size: 24rpx;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #787898;
      line-height: 24rpx;
    }
  }
  .phone-box {
    width: 202rpx;
    height: 66rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.8);
    border-radius: 34rpx;
    border: 4rpx solid #FFFFFF;
    margin-left: 12rpx;
    .phone-img {
      width: 38rpx;
      height: 38rpx;
      margin-right: 8rpx;
    }
    text {
      height: 40rpx;
      font-weight: 600;
      font-size: 28rpx;
      color: #404062;
      line-height: 40rpx;
    }
  }
   .mapClass_click{
      display: flex;
      align-items: center;
      height: 66rpx;
      background: rgba(255,255,255,0.8);
      border-radius: 34rpx;
      font-weight: 600;
      font-size: 28rpx;
      color: #404062;
      line-height: 66rpx;
      padding: 0 22rpx;
      margin-left: 16rpx;
    }
    .mapClass_img{
      width: 38rpx;
      height: 38rpx;
      margin-right: 8rpx;
    }
  </style>
  